bitkeeper revision 1.1534.1.1 (429399e0oJudIjoFsgWFxNKnCM7qTg)
authorcl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>
Tue, 24 May 2005 21:17:20 +0000 (21:17 +0000)
committercl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>
Tue, 24 May 2005 21:17:20 +0000 (21:17 +0000)
Nothing but vnet uses libxutil -- move it there.
Makefile, xc.c, setup.py, configure, configure.in, Makefile.in:
  This doesn't use libxutil.
Makefile, Makefile.vnet, Rules.mk:
  Move libxutil into vnet since it's only used there.
Many files:
  mvdir

88 files changed:
.rootkeys
tools/Makefile
tools/Rules.mk
tools/blktap/Makefile
tools/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/Makefile.in
tools/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure
tools/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure.in
tools/ioemu/target-i386-dm/Makefile
tools/libxc/Makefile
tools/libxc/xc_private.h
tools/libxutil/Makefile [deleted file]
tools/libxutil/allocate.c [deleted file]
tools/libxutil/allocate.h [deleted file]
tools/libxutil/debug.h [deleted file]
tools/libxutil/enum.c [deleted file]
tools/libxutil/enum.h [deleted file]
tools/libxutil/fd_stream.c [deleted file]
tools/libxutil/fd_stream.h [deleted file]
tools/libxutil/file_stream.c [deleted file]
tools/libxutil/file_stream.h [deleted file]
tools/libxutil/gzip_stream.c [deleted file]
tools/libxutil/gzip_stream.h [deleted file]
tools/libxutil/hash_table.c [deleted file]
tools/libxutil/hash_table.h [deleted file]
tools/libxutil/iostream.c [deleted file]
tools/libxutil/iostream.h [deleted file]
tools/libxutil/kernel_stream.c [deleted file]
tools/libxutil/kernel_stream.h [deleted file]
tools/libxutil/lexis.c [deleted file]
tools/libxutil/lexis.h [deleted file]
tools/libxutil/socket_stream.c [deleted file]
tools/libxutil/socket_stream.h [deleted file]
tools/libxutil/string_stream.c [deleted file]
tools/libxutil/string_stream.h [deleted file]
tools/libxutil/sxpr.c [deleted file]
tools/libxutil/sxpr.h [deleted file]
tools/libxutil/sxpr_parser.c [deleted file]
tools/libxutil/sxpr_parser.h [deleted file]
tools/libxutil/sys_net.c [deleted file]
tools/libxutil/sys_net.h [deleted file]
tools/libxutil/sys_string.c [deleted file]
tools/libxutil/sys_string.h [deleted file]
tools/libxutil/util.c [deleted file]
tools/libxutil/util.h [deleted file]
tools/misc/Makefile
tools/misc/cpuperf/Makefile
tools/python/setup.py
tools/python/xen/lowlevel/xc/xc.c
tools/vnet/Makefile
tools/vnet/libxutil/Makefile [new file with mode: 0644]
tools/vnet/libxutil/allocate.c [new file with mode: 0644]
tools/vnet/libxutil/allocate.h [new file with mode: 0644]
tools/vnet/libxutil/debug.h [new file with mode: 0644]
tools/vnet/libxutil/enum.c [new file with mode: 0644]
tools/vnet/libxutil/enum.h [new file with mode: 0644]
tools/vnet/libxutil/fd_stream.c [new file with mode: 0644]
tools/vnet/libxutil/fd_stream.h [new file with mode: 0644]
tools/vnet/libxutil/file_stream.c [new file with mode: 0644]
tools/vnet/libxutil/file_stream.h [new file with mode: 0644]
tools/vnet/libxutil/gzip_stream.c [new file with mode: 0644]
tools/vnet/libxutil/gzip_stream.h [new file with mode: 0644]
tools/vnet/libxutil/hash_table.c [new file with mode: 0644]
tools/vnet/libxutil/hash_table.h [new file with mode: 0644]
tools/vnet/libxutil/iostream.c [new file with mode: 0644]
tools/vnet/libxutil/iostream.h [new file with mode: 0644]
tools/vnet/libxutil/kernel_stream.c [new file with mode: 0644]
tools/vnet/libxutil/kernel_stream.h [new file with mode: 0644]
tools/vnet/libxutil/lexis.c [new file with mode: 0644]
tools/vnet/libxutil/lexis.h [new file with mode: 0644]
tools/vnet/libxutil/socket_stream.c [new file with mode: 0644]
tools/vnet/libxutil/socket_stream.h [new file with mode: 0644]
tools/vnet/libxutil/string_stream.c [new file with mode: 0644]
tools/vnet/libxutil/string_stream.h [new file with mode: 0644]
tools/vnet/libxutil/sxpr.c [new file with mode: 0644]
tools/vnet/libxutil/sxpr.h [new file with mode: 0644]
tools/vnet/libxutil/sxpr_parser.c [new file with mode: 0644]
tools/vnet/libxutil/sxpr_parser.h [new file with mode: 0644]
tools/vnet/libxutil/sys_net.c [new file with mode: 0644]
tools/vnet/libxutil/sys_net.h [new file with mode: 0644]
tools/vnet/libxutil/sys_string.c [new file with mode: 0644]
tools/vnet/libxutil/sys_string.h [new file with mode: 0644]
tools/vnet/libxutil/util.c [new file with mode: 0644]
tools/vnet/libxutil/util.h [new file with mode: 0644]
tools/vnet/vnet-module/Makefile.vnet
tools/vnet/vnetd/Makefile
tools/xcs/Makefile
tools/xcutils/Makefile
tools/xentrace/Makefile

index 3526ae3342ef7848532a9abb06475cb83b124776..141b21cf73de063abba019768ec0d4eea3d26f90 100644 (file)
--- a/.rootkeys
+++ b/.rootkeys
 4273458duzL--nsTfT6e_q6Kfij48g tools/libxc/xc_ptrace_core.c
 41ebbfe9U0b0kI-HgjK7VEY4EvW7_w tools/libxc/xc_sedf.c
 41dde8b0pLfAKMs_L9Uri2hnzHiCRQ tools/libxc/xc_vmx_build.c
-40e1b09dMYB4ItGCqcMIzirdMd9I-w tools/libxutil/Makefile
-40e033325Sjqs-_4TuzeUEprP_gYFg tools/libxutil/allocate.c
-40e03332KYz7o1bn2MG_KPbBlyoIMA tools/libxutil/allocate.h
-41a216cav5JJbtDQnusfuMa_1x_Xpw tools/libxutil/debug.h
-40e9808eyjiahG5uF6AMelNVujBzCg tools/libxutil/enum.c
-40e9808eZpbdn9q2KSSMGCNvY_ZgpQ tools/libxutil/enum.h
-4284c2ecWyadIhHF1u_QSgWqIXkaLA tools/libxutil/fd_stream.c
-4284c2ecEOOcF6fZUf_NsZzYAoNo-w tools/libxutil/fd_stream.h
-40e03332p5Dc_owJQRuN72ymJZddFQ tools/libxutil/file_stream.c
-40e03332jWfB2viAhLSkq1WK0r_iDQ tools/libxutil/file_stream.h
-40e03332rUjNMGg11n2rN6V4DCrvOg tools/libxutil/gzip_stream.c
-40e033321O5Qg22haLoq5lpmk4tooQ tools/libxutil/gzip_stream.h
-40e9808easXCzzAZQodEfKAhgUXSPA tools/libxutil/hash_table.c
-40e9808e94BNXIVVKBFHC3rnkvwtJg tools/libxutil/hash_table.h
-40e03332ihnBGzHykVwZnFmkAppb4g tools/libxutil/iostream.c
-40e03332UGwbLR4wsw4ft14p0Yw5pg tools/libxutil/iostream.h
-40e0333245DLDzJemeSVBLuutHtzEQ tools/libxutil/kernel_stream.c
-40e03332aK0GkgpDdc-PVTkWKTeOBg tools/libxutil/kernel_stream.h
-40e9808epW9iHcLXuO3QfUfLzB7onw tools/libxutil/lexis.c
-40e9808egccMhCizayQRGtpBA3L5MQ tools/libxutil/lexis.h
-41a216caM4z39Fzjb91rv9Ed_4By1A tools/libxutil/socket_stream.c
-41a216caqinvF1I5FQMHA4HTRz8MSA tools/libxutil/socket_stream.h
-40e03332KT_tnnoAMbPVAZBB7kSOAQ tools/libxutil/string_stream.c
-40e03332-VtK6_OZa1vMHXFil8uq6w tools/libxutil/string_stream.h
-40e9808e5_PLdodqVOSx0b4T_f5aeg tools/libxutil/sxpr.c
-40e9808e0O4sHZtkDv5hlSqjYcdQAQ tools/libxutil/sxpr.h
-40ec1cc6SIiGbynOi-1NtPesOlzF-Q tools/libxutil/sxpr_parser.c
-40ec1cc6wpvvGxZiq4EFvNOcw0tUFg tools/libxutil/sxpr_parser.h
-40e03332Rkvq6nn_UNjzAAK_Tk9v1g tools/libxutil/sys_net.c
-40e03332lQHvQHw4Rh7VsT1_sui29A tools/libxutil/sys_net.h
-40e033321smklZd7bDSdWvQCeIshtg tools/libxutil/sys_string.c
-40e03332h5V611rRWURRLqb1Ekatxg tools/libxutil/sys_string.h
-41a216cayFe2FQroFuzvNPw1AvNiqQ tools/libxutil/util.c
-41a216ca7mgVSnCBHPCLkGOIqPS1CQ tools/libxutil/util.h
 3f776bd2Xd-dUcPKlPN2vG89VGtfvQ tools/misc/Makefile
 4225f56d7sa9aEARfjNeCVTMYDAmZA tools/misc/cpuperf/Makefile
 4225f56dS5TGdKojmuBnrV3PzbE6Rg tools/misc/cpuperf/README.txt
 41a21888QPgKrulCfR9SY_pxZKU0KA tools/vnet/examples/vnet97.sxp
 41a21888Gm0UBs1i7HqveT7Yz0u8DQ tools/vnet/examples/vnet98.sxp
 41a21888r4oGPuGv2Lxl-thgV3H54w tools/vnet/examples/vnet99.sxp
+40e1b09dMYB4ItGCqcMIzirdMd9I-w tools/vnet/libxutil/Makefile
+40e033325Sjqs-_4TuzeUEprP_gYFg tools/vnet/libxutil/allocate.c
+40e03332KYz7o1bn2MG_KPbBlyoIMA tools/vnet/libxutil/allocate.h
+41a216cav5JJbtDQnusfuMa_1x_Xpw tools/vnet/libxutil/debug.h
+40e9808eyjiahG5uF6AMelNVujBzCg tools/vnet/libxutil/enum.c
+40e9808eZpbdn9q2KSSMGCNvY_ZgpQ tools/vnet/libxutil/enum.h
+4284c2ecWyadIhHF1u_QSgWqIXkaLA tools/vnet/libxutil/fd_stream.c
+4284c2ecEOOcF6fZUf_NsZzYAoNo-w tools/vnet/libxutil/fd_stream.h
+40e03332p5Dc_owJQRuN72ymJZddFQ tools/vnet/libxutil/file_stream.c
+40e03332jWfB2viAhLSkq1WK0r_iDQ tools/vnet/libxutil/file_stream.h
+40e03332rUjNMGg11n2rN6V4DCrvOg tools/vnet/libxutil/gzip_stream.c
+40e033321O5Qg22haLoq5lpmk4tooQ tools/vnet/libxutil/gzip_stream.h
+40e9808easXCzzAZQodEfKAhgUXSPA tools/vnet/libxutil/hash_table.c
+40e9808e94BNXIVVKBFHC3rnkvwtJg tools/vnet/libxutil/hash_table.h
+40e03332ihnBGzHykVwZnFmkAppb4g tools/vnet/libxutil/iostream.c
+40e03332UGwbLR4wsw4ft14p0Yw5pg tools/vnet/libxutil/iostream.h
+40e0333245DLDzJemeSVBLuutHtzEQ tools/vnet/libxutil/kernel_stream.c
+40e03332aK0GkgpDdc-PVTkWKTeOBg tools/vnet/libxutil/kernel_stream.h
+40e9808epW9iHcLXuO3QfUfLzB7onw tools/vnet/libxutil/lexis.c
+40e9808egccMhCizayQRGtpBA3L5MQ tools/vnet/libxutil/lexis.h
+41a216caM4z39Fzjb91rv9Ed_4By1A tools/vnet/libxutil/socket_stream.c
+41a216caqinvF1I5FQMHA4HTRz8MSA tools/vnet/libxutil/socket_stream.h
+40e03332KT_tnnoAMbPVAZBB7kSOAQ tools/vnet/libxutil/string_stream.c
+40e03332-VtK6_OZa1vMHXFil8uq6w tools/vnet/libxutil/string_stream.h
+40e9808e5_PLdodqVOSx0b4T_f5aeg tools/vnet/libxutil/sxpr.c
+40e9808e0O4sHZtkDv5hlSqjYcdQAQ tools/vnet/libxutil/sxpr.h
+40ec1cc6SIiGbynOi-1NtPesOlzF-Q tools/vnet/libxutil/sxpr_parser.c
+40ec1cc6wpvvGxZiq4EFvNOcw0tUFg tools/vnet/libxutil/sxpr_parser.h
+40e03332Rkvq6nn_UNjzAAK_Tk9v1g tools/vnet/libxutil/sys_net.c
+40e03332lQHvQHw4Rh7VsT1_sui29A tools/vnet/libxutil/sys_net.h
+40e033321smklZd7bDSdWvQCeIshtg tools/vnet/libxutil/sys_string.c
+40e03332h5V611rRWURRLqb1Ekatxg tools/vnet/libxutil/sys_string.h
+41a216cayFe2FQroFuzvNPw1AvNiqQ tools/vnet/libxutil/util.c
+41a216ca7mgVSnCBHPCLkGOIqPS1CQ tools/vnet/libxutil/util.h
 41a21888c9TCRlUwJS9WBjB3e9aWgg tools/vnet/vnet-module/00README
 41a21888K2ItolEkksc1MUqyTDI_Kg tools/vnet/vnet-module/Makefile
 41a21888mJsFJD7bVMm-nrnWnalGBw tools/vnet/vnet-module/Makefile-2.4
index 2ffa48132808f1f416c56dd426b0f8f5ad57e570..4e29741f5f64ee2df2aaf64b327d9614c7f07338 100644 (file)
@@ -2,7 +2,6 @@ XEN_ROOT = ../
 include $(XEN_ROOT)/tools/Rules.mk
 
 SUBDIRS :=
-SUBDIRS += libxutil
 SUBDIRS += libxc
 SUBDIRS += misc
 SUBDIRS += examples
index 6e811b9611d0d1e7542b80e56dc023e841dec35f..5b79d37ff74440600ad2ddf23ce7de6b5ce10fce 100644 (file)
@@ -4,7 +4,6 @@ include $(XEN_ROOT)/Config.mk
 
 XEN_XC             = $(XEN_ROOT)/tools/python/xen/lowlevel/xc
 XEN_LIBXC          = $(XEN_ROOT)/tools/libxc
-XEN_LIBXUTIL       = $(XEN_ROOT)/tools/libxutil
 
 ifeq ($(XEN_TARGET_ARCH),x86_32)
 CFLAGS  += -m32 -march=i686
index 26187de77963757f9fd98afc74941d48ee77fc4b..9807e053874d9723803ea96cc2b44b29cf94a45f 100644 (file)
@@ -47,7 +47,6 @@ CFLAGS   += -Wno-unused
 CFLAGS   += -g3
 CFLAGS   += -fno-strict-aliasing
 CFLAGS   += -I $(XEN_LIBXC)
-CFLAGS   += -I $(XEN_LIBXUTIL)
 CFLAGS   += $(INCLUDES) -I.
 CFLAGS   += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE
 # Get gcc to generate the dependencies for us.
@@ -97,16 +96,16 @@ libblktap.so:
 libblktap.so.$(MAJOR):
        ln -sf libblktap.so.$(MAJOR).$(MINOR) $@
 libblktap.so.$(MAJOR).$(MINOR): $(OBJS)
-       $(CC) -Wl,-soname -Wl,$(SONAME) -shared -o $@ $^ -lpthread -L../libxutil -lxutil -lz
+       $(CC) -Wl,-soname -Wl,$(SONAME) -shared -o $@ $^ -lpthread -lz
 
 blkdump: $(LIB)
-       $(CC) $(CFLAGS) -o blkdump -L$(XEN_LIBXC) -L$(XEN_LIBXUTIL) -L. -l blktap blkdump.c
+       $(CC) $(CFLAGS) -o blkdump -L$(XEN_LIBXC) -L. -l blktap blkdump.c
 
 parallax: $(LIB) $(PLX_SRCS)
-       $(CC) $(CFLAGS) -o parallax -L$(XEN_LIBXC) -L$(XEN_LIBXUTIL) -L. -lblktap -lpthread $(PLX_SRCS) 
+       $(CC) $(CFLAGS) -o parallax -L$(XEN_LIBXC) -L. -lblktap -lpthread $(PLX_SRCS) 
 
 parallax-threaded: $(LIB) $(PLXT_SRCS)
-       $(CC) $(CFLAGS) -o parallax-threaded -L$(XEN_LIBXC) -L$(XEN_LIBXUTIL) -L. -lpthread -lblktap $(PLXT_SRCS)
+       $(CC) $(CFLAGS) -o parallax-threaded -L$(XEN_LIBXC) -L. -lpthread -lblktap $(PLXT_SRCS)
 
 vdi_list: $(LIB) vdi_list.c $(VDI_SRCS)
        $(CC) $(CFLAGS) -g3 -o vdi_list vdi_list.c -lpthread $(VDI_SRCS)
index 93f177387cd12bdfe02d98febb3143bc5b103ccc..f6843357e7c022ec45549f6a62c71aa648703ded 100644 (file)
@@ -83,7 +83,7 @@ READLINE_DEP = $$(READLINE_DIR)
 # -I. for config files.
 # -I${srcdir} for our headers.
 # -I$(srcdir)/../regformats for regdef.h.
-INCLUDE_CFLAGS = -I. -I${srcdir} -I$(srcdir)/../regformats -I$(INCLUDE_DIR)  -I../../../../libxc/ -I../../../../libxutil/
+INCLUDE_CFLAGS = -I. -I${srcdir} -I$(srcdir)/../regformats -I$(INCLUDE_DIR)  -I../../../../libxc/
 
 # M{H,T}_CFLAGS, if defined, has host- and target-dependent CFLAGS
 # from the config/ directory.
index e81046517a6d982784d9a38989104586c632e84d..d45d933ab3efc2b750a48c6f3a7925f3af7adaec 100755 (executable)
@@ -3475,7 +3475,7 @@ USE_THREAD_DB=
 
 
 GDBSERVER_DEPFILES="$srv_regobj $srv_tgtobj $srv_thread_depfiles"
-GDBSERVER_LIBS="$srv_libs -L../../../../libxc/ -L../../../../libxutil/ -lxc -lxutil"
+GDBSERVER_LIBS="$srv_libs -L../../../../libxc/ -lxc"
 
 
 
index 032eabe345c8122e0c00fa4e70f367bf6b7562ac..1d5c22af0b555a2507188d1956112d05e456f54c 100644 (file)
@@ -107,7 +107,7 @@ USE_THREAD_DB=
 
 
 GDBSERVER_DEPFILES="$srv_regobj $srv_tgtobj $srv_thread_depfiles"
-GDBSERVER_LIBS="$srv_libs -L../../../../libxc/ -L../../../../libxutil/ -lxc -lxutil"
+GDBSERVER_LIBS="$srv_libs -L../../../../libxc/ -lxc"
 
 AC_SUBST(GDBSERVER_DEPFILES)
 AC_SUBST(GDBSERVER_LIBS)
index 385f8388002d06d4ce6fd34048f70afc75b73ca3..945f38178e334d83b3999ca6e7dbe2abd0af0203 100644 (file)
@@ -189,7 +189,7 @@ endif
 #########################################################
 
 DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
-LIBS+=-lm -L../../libxc -L../../libxutil -lxc -lxutil
+LIBS+=-lm -L../../libxc -lxc
 ifndef CONFIG_USER_ONLY
 LIBS+=-lz
 endif
index e5db1adcf6f1cb91b81c371aaf6d31f30eaeb265..66f01d94897c7d8dca505a54a740bf39bb7afd41 100644 (file)
@@ -12,9 +12,6 @@ CC       = gcc
 XEN_ROOT = ../..
 include $(XEN_ROOT)/tools/Rules.mk
 
-vpath %c       $(XEN_LIBXUTIL)
-INCLUDES += -I $(XEN_LIBXUTIL)
-
 SRCS     :=
 SRCS     += xc_sedf.c
 SRCS     += xc_bvtsched.c
@@ -105,6 +102,6 @@ libxc.so.$(MAJOR): libxc.so.$(MAJOR).$(MINOR)
        ln -sf $< $@
 
 libxc.so.$(MAJOR).$(MINOR): $(PIC_OBJS)
-       $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libxc.so.$(MAJOR) -shared -o $@ $^ -L../libxutil -lxutil -lz
+       $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libxc.so.$(MAJOR) -shared -o $@ $^ -lz
 
 -include $(DEPS)
index f454b5e9b165a42fd3bf6e81242a764ba8931778..ec8b21c21c6d0d0477a7ab5160d289215f9d6e5a 100644 (file)
@@ -232,8 +232,6 @@ typedef struct mfn_mapper {
     
 } mfn_mapper_t;
 
-#include "xc_io.h"
-
 unsigned long xc_get_m2p_start_mfn ( int xc_handle );
 
 long xc_get_tot_pages(int xc_handle, u32 domid);
diff --git a/tools/libxutil/Makefile b/tools/libxutil/Makefile
deleted file mode 100644 (file)
index 1a3ed9b..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-
-XEN_ROOT = ../..
-INSTALL                = install
-INSTALL_DATA   = $(INSTALL) -m0644
-INSTALL_PROG   = $(INSTALL) -m0755
-INSTALL_DIR    = $(INSTALL) -d -m0755
-
-include $(XEN_ROOT)/tools/Rules.mk
-
-LIB_SRCS :=
-LIB_SRCS += allocate.c
-LIB_SRCS += enum.c
-LIB_SRCS += file_stream.c
-LIB_SRCS += gzip_stream.c
-LIB_SRCS += hash_table.c
-LIB_SRCS += iostream.c
-LIB_SRCS += lexis.c
-LIB_SRCS += string_stream.c
-LIB_SRCS += sxpr.c
-LIB_SRCS += sxpr_parser.c
-LIB_SRCS += sys_net.c
-LIB_SRCS += sys_string.c
-LIB_SRCS += util.c
-
-LIB_OBJS := $(LIB_SRCS:.c=.o)
-PIC_OBJS := $(LIB_SRCS:.c=.opic)
-
-CFLAGS   += -Wall -Werror -O3 -fno-strict-aliasing
-
-# Get gcc to generate the dependencies for us.
-CFLAGS   += -Wp,-MD,.$(@F).d
-DEPS     = .*.d
-
-MAJOR    := 3.0
-MINOR    := 0
-LIB      := libxutil.so 
-LIB      += libxutil.so.$(MAJOR)
-LIB      += libxutil.so.$(MAJOR).$(MINOR)
-LIB      += libxutil.a
-
-all: build
-build: check-for-zlib
-       $(MAKE) $(LIB)
-
-libxutil.so: libxutil.so.$(MAJOR)
-       ln -sf $^ $@
-
-libxutil.so.$(MAJOR): libxutil.so.$(MAJOR).$(MINOR)
-       ln -sf $^ $@
-
-libxutil.so.$(MAJOR).$(MINOR): $(PIC_OBJS)
-       $(CC) $(CFLAGS) -Wl,-soname -Wl,libxutil.so.$(MAJOR) -shared -o $@ $^
-
-libxutil.a: $(LIB_OBJS)
-       $(AR) rc $@ $^
-
-check-for-zlib:
-       @if [ ! -e /usr/include/zlib.h ]; then \
-       echo "***********************************************************"; \
-       echo "ERROR: install zlib header files (http://www.gzip.org/zlib)"; \
-       echo "***********************************************************"; \
-       false; \
-       fi
-
-install: build
-       [ -d $(DESTDIR)/usr/$(LIBDIR) ] || $(INSTALL_DIR) -p $(DESTDIR)/usr/$(LIBDIR)
-       $(INSTALL_PROG) libxutil.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)
-       $(INSTALL_DATA) libxutil.a $(DESTDIR)/usr/$(LIBDIR)
-       ln -sf libxutil.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)/libxutil.so.$(MAJOR)
-       ln -sf libxutil.so.$(MAJOR) $(DESTDIR)/usr/$(LIBDIR)/libxutil.so
-
-clean:
-       $(RM) *.a *.so* *.o *.opic *.rpm 
-       $(RM) *~
-       $(RM) $(DEPS)
-
--include $(DEPS)
diff --git a/tools/libxutil/allocate.c b/tools/libxutil/allocate.c
deleted file mode 100644 (file)
index 600ebab..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "allocate.h"
-
-/** @file
- * Support for allocating memory.
- * Usable from user code or kernel code (with __KERNEL__ defined).
- * In user code will use GC if USE_GC is defined.
- */
-
-#ifdef __KERNEL__
-/*----------------------------------------------------------------------------*/
-#  include <linux/config.h>
-#  include <linux/slab.h>
-#  include <linux/string.h>
-#  include <linux/types.h>
-
-#  define DEFAULT_TYPE    0
-#  define MALLOC(n, type) kmalloc(n, type)
-#  define FREE(ptr)       kfree(ptr)
-
-/*----------------------------------------------------------------------------*/
-#else /* ! __KERNEL__ */
-
-#  include <stdlib.h>
-#  include <string.h>
-
-#  define DEFAULT_TYPE    0
-
-#ifdef USE_GC
-#  include "gc.h"
-#  define MALLOC(n, typ)  GC_malloc(n)
-#  define FREE(ptr)       (ptr=NULL)
-//typedef void *GC_PTR;
-//GC_PTR (*GC_oom_fn)(size_t n);
-#else
-#  define MALLOC(n, type) malloc(n)
-#  define FREE(ptr)       free(ptr)
-#endif
-
-/*----------------------------------------------------------------------------*/
-#endif
-
-/** Function to call when memory cannot be allocated. */
-AllocateFailedFn *allocate_failed_fn = NULL;
-
-/** Allocate memory and zero it.
- * The type is only relevant when calling from kernel code,
- * from user code it is ignored.
- * In kernel code the values accepted by kmalloc can be used:
- * GFP_USER, GFP_ATOMIC, GFP_KERNEL.
- *
- * @param size number of bytes to allocate
- * @param type memory type to allocate (kernel only)
- * @return pointer to the allocated memory or zero
- * if malloc failed
- */
-void *allocate_type(int size, int type){
-    void *p = MALLOC(size, type);
-    if(p){
-        memzero(p, size);
-    } else if(allocate_failed_fn){
-        allocate_failed_fn(size, type);
-    }
-    return p;
-}
-
-/** Allocate memory and zero it.
- *
- * @param size number of bytes to allocate
- * @return pointer to the allocated memory or zero
- * if malloc failed
- */
-void *allocate(int size){
-    return allocate_type(size, DEFAULT_TYPE);
-}
-
-/** Free memory allocated by allocate().
- * No-op if 'p' is null.
- *
- * @param p memory to free
- */
-void deallocate(void *p){
-    if(p){
-        FREE(p);
-    }
-}
-
-/** Set bytes to zero.
- * No-op if 'p' is null.
- *
- * @param p memory to zero
- * @param size number of bytes to zero
- */
-void memzero(void *p, int size){
-    if(p){
-        memset(p, 0, (size_t)size);
-    }
-}
-
diff --git a/tools/libxutil/allocate.h b/tools/libxutil/allocate.h
deleted file mode 100644 (file)
index 391b7be..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XUTIL_ALLOCATE_H_
-#define _XUTIL_ALLOCATE_H_
-
-/** Allocate memory for a given type, and cast. */
-#define ALLOCATE(ctype) (ctype *)allocate(sizeof(ctype))
-
-/** Allocate memory for a given type, and cast. */
-#define ALLOCATE_TYPE(ctype, type) (ctype *)allocate(sizeof(ctype))
-
-extern void *allocate_type(int size, int type);
-extern void *allocate(int size);
-extern void deallocate(void *);
-extern void memzero(void *p, int size);
-
-typedef void AllocateFailedFn(int size, int type);
-extern AllocateFailedFn *allocate_failed_fn;
-
-#endif /* _XUTIL_ALLOCATE_H_ */
-
-
-
-
-
-
-
-
-
diff --git a/tools/libxutil/debug.h b/tools/libxutil/debug.h
deleted file mode 100644 (file)
index 1f5a19d..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef _XUTIL_DEBUG_H_
-#define _XUTIL_DEBUG_H_
-
-#ifndef MODULE_NAME
-#define MODULE_NAME ""
-#endif
-
-#ifdef __KERNEL__
-#include <linux/config.h>
-#include <linux/kernel.h>
-
-#ifdef DEBUG
-
-#define dprintf(fmt, args...) printk(KERN_DEBUG   "[DBG] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args)
-#define wprintf(fmt, args...) printk(KERN_WARNING "[WRN] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args)
-#define iprintf(fmt, args...) printk(KERN_INFO    "[INF] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args)
-#define eprintf(fmt, args...) printk(KERN_ERR     "[ERR] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args)
-
-#else
-
-#define dprintf(fmt, args...) do {} while(0)
-#define wprintf(fmt, args...) printk(KERN_WARNING "[WRN] " MODULE_NAME fmt, ##args)
-#define iprintf(fmt, args...) printk(KERN_INFO    "[INF] " MODULE_NAME fmt, ##args)
-#define eprintf(fmt, args...) printk(KERN_ERR     "[ERR] " MODULE_NAME fmt, ##args)
-
-#endif
-
-#else
-
-#include <stdio.h>
-
-#ifdef DEBUG
-
-#define dprintf(fmt, args...) fprintf(stdout, "%d [DBG] " MODULE_NAME ">%s" fmt, getpid(), __FUNCTION__, ##args)
-#define wprintf(fmt, args...) fprintf(stderr, "%d [WRN] " MODULE_NAME ">%s" fmt, getpid(),__FUNCTION__, ##args)
-#define iprintf(fmt, args...) fprintf(stderr, "%d [INF] " MODULE_NAME ">%s" fmt, getpid(),__FUNCTION__, ##args)
-#define eprintf(fmt, args...) fprintf(stderr, "%d [ERR] " MODULE_NAME ">%s" fmt, getpid(),__FUNCTION__, ##args)
-
-#else
-
-#define dprintf(fmt, args...) do {} while(0)
-#define wprintf(fmt, args...) fprintf(stderr, "%d [WRN] " MODULE_NAME fmt, getpid(), ##args)
-#define iprintf(fmt, args...) fprintf(stderr, "%d [INF] " MODULE_NAME fmt, getpid(), ##args)
-#define eprintf(fmt, args...) fprintf(stderr, "%d [ERR] " MODULE_NAME fmt, getpid(), ##args)
-
-#endif
-
-#endif
-
-/** Print format for an IP address.
- * See NIPQUAD(), HIPQUAD()
- */
-#define IPFMT "%u.%u.%u.%u"
-
-#endif /* ! _XUTIL_DEBUG_H_ */
diff --git a/tools/libxutil/enum.c b/tools/libxutil/enum.c
deleted file mode 100644 (file)
index 95f6e31..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2002, 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#ifdef __KERNEL__
-#include <linux/errno.h>
-#else
-#include <errno.h>
-#endif
-
-#include "sys_string.h"
-#include "enum.h"
-
-/** Map an enum name to its value using a table.
- *
- * @param name enum name
- * @param defs enum definitions
- * @return enum value or -1 if not known
- */
-int enum_name_to_val(char *name, EnumDef *defs){
-    int val = -1;
-    for(; defs->name; defs++){
-       if(!strcmp(defs->name, name)){
-           val = defs->val;
-           break;
-       }
-    }
-    return val;
-}
-
-/** Map an enum value to its name using a table.
- *
- * @param val enum value
- * @param defs enum definitions
- * @param defs_n number of definitions
- * @return enum name or NULL if not known
- */
-char *enum_val_to_name(int val, EnumDef *defs){
-    char *name = NULL;
-    for(; defs->name; defs++){
-       if(val == defs->val){
-           name = defs->name;
-           break;
-       }
-    }
-    return name;
-}
-
diff --git a/tools/libxutil/enum.h b/tools/libxutil/enum.h
deleted file mode 100644 (file)
index cdc0f6f..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2002, 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#ifndef _XUTIL_ENUM_H_
-#define _XUTIL_ENUM_H_
-
-/** Mapping of an enum value to a name. */
-typedef struct EnumDef {
-    int val;
-    char *name;
-} EnumDef;
-
-extern int enum_name_to_val(char *name, EnumDef *defs);
-extern char *enum_val_to_name(int val, EnumDef *defs);
-
-#endif /* _XUTIL_ENUM_H_ */
diff --git a/tools/libxutil/fd_stream.c b/tools/libxutil/fd_stream.c
deleted file mode 100644 (file)
index 428f0a5..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/** @file
- * An IOStream implementation using fds.
- */
-#ifndef __KERNEL__
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include "allocate.h"
-#include "fd_stream.h"
-
-#define MODULE_NAME "fd_stream"
-#define DEBUG 1
-//#undef DEBUG
-#include "debug.h"
-
-static int fd_read(IOStream *s, void *buf, size_t n);
-static int fd_write(IOStream *s, const void *buf, size_t n);
-static int fd_error(IOStream *s);
-static int fd_close(IOStream *s);
-static void fd_free(IOStream *s);
-static int fd_flush(IOStream *s);
-
-/** Methods used by a fd IOStream. */
-static const IOMethods fd_methods = {
-    read:  fd_read,
-    write: fd_write,
-    error: fd_error,
-    close: fd_close,
-    free:  fd_free,
-    flush: fd_flush,
-};
-
-/** Get the fd data.
- * 
- * @param io fd stream
- * @return data
- */
-static inline FDData * fd_data(IOStream *io){
-    return (FDData *)io->data;
-}
-
-/** Test if a stream is a fd stream.
- *
- * @param io stream
- * @return 0 if a fd stream, -EINVAL if not
- */
-int fd_stream_check(IOStream *io){
-    return (io && io->methods == &fd_methods ? 0 : -EINVAL);
-}
-
-/** Get the data for a fd stream.
- *
- * @param io stream
- * @param data return value for the data
- * @return 0 if a fd stream, -EINVAL if not
- */
-int fd_stream_data(IOStream *io, FDData **data){
-    int err = fd_stream_check(io);
-    if(err){
-        *data = NULL;
-    } else {
-        *data = fd_data(io);
-    }
-    return err;
-}
-
-
-/** Write to the underlying fd.
- *
- * @param stream input
- * @param buf where to put input
- * @param n number of bytes to write
- * @return number of bytes written
- */
-static int fd_write(IOStream *s, const void *buf, size_t n){
-    FDData *data = fd_data(s);
-    int k;
-    k = write(data->fd, buf, n);
-    return k;
-}
-
-/** Read from the underlying stream;
- *
- * @param stream input
- * @param buf where to put input
- * @param n number of bytes to read
- * @return number of bytes read
- */
-static int fd_read(IOStream *s, void *buf, size_t n){
-    FDData *data = fd_data(s);
-    int k;
-    k = read(data->fd, buf, n);
-    //printf("> fd_read> buf=%p n=%d --> k=%d\n", buf, n, k);
-    return k;
-}
-
-/** Flush the fd (no-op).
- *
- * @param s fd stream
- * @return 0 on success, error code otherwise
- */
-static int fd_flush(IOStream *s){
-    return 0;
-}
-
-/** Check if a fd stream has an error (no-op).
- *
- * @param s fd stream
- * @return 1 if has an error, 0 otherwise
- */
-static int fd_error(IOStream *s){
-    return 0;
-}
-
-/** Close a fd stream.
- *
- * @param s fd stream to close
- * @return result of the close
- */
-static int fd_close(IOStream *s){
-    FDData *data = fd_data(s);
-    return close(data->fd);
-}
-
-/** Free a fd stream.
- *
- * @param s fd stream
- */
-static void fd_free(IOStream *s){
-    FDData *data = fd_data(s);
-    deallocate(data);
-}
-
-/** Create an IOStream for a fd.
- *
- * @param fd fd to wtap
- * @return new IOStream using fd for i/o
- */
-IOStream *fd_stream_new(int fd){
-    int err = -ENOMEM;
-    IOStream *io = NULL;
-    FDData *data = NULL;
-
-    io = ALLOCATE(IOStream);
-    if(!io) goto exit;
-    io->methods = &fd_methods;
-    data = ALLOCATE(FDData);
-    if(!data) goto exit;
-    io->data = data;
-    data->fd = fd;
-    err = 0;
-  exit:
-    if(err){
-        if(io){
-            if(data) deallocate(data);
-            deallocate(io);
-            io = NULL;
-        }
-    }
-    return io;
-}
-
-#endif
diff --git a/tools/libxutil/fd_stream.h b/tools/libxutil/fd_stream.h
deleted file mode 100644 (file)
index b37a686..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XMC_FD_STREAM_H_
-#define _XMC_FD_STREAM_H_
-
-#ifndef __KERNEL__
-#include "iostream.h"
-
-/** Data associated with a fd stream. */
-typedef struct FDData {
-    /** The socket file descriptor. */
-    int fd;
-} FDData;
-
-extern IOStream *fd_stream_new(int fd);
-extern int fd_stream_data(IOStream *io, FDData **data);
-extern int fd_stream_check(IOStream *io);
-
-#endif
-#endif /* !_XMC_FD_STREAM_H_ */
diff --git a/tools/libxutil/file_stream.c b/tools/libxutil/file_stream.c
deleted file mode 100644 (file)
index 7adbac0..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/** @file
- * An IOStream implementation using FILE*.
- */
-#ifndef __KERNEL__
-#include <stdio.h>
-#include <stdlib.h>
-#include "allocate.h"
-#include "file_stream.h"
-
-static int file_read(IOStream *s, void *buf, size_t n);
-static int file_write(IOStream *s, const void *buf, size_t n);
-static int file_error(IOStream *s);
-static int file_close(IOStream *s);
-static void file_free(IOStream *s);
-static int file_flush(IOStream *s);
-
-/** Methods used by a FILE* IOStream. */
-static const IOMethods file_methods = {
-    read:  file_read,
-    write: file_write,
-    error: file_error,
-    close: file_close,
-    free:  file_free,
-    flush: file_flush,
-};
-
-/** IOStream for stdin. */
-static IOStream _iostdin = {
-    methods: &file_methods,
-    data: (void*)1,
-    nofree: 1,
-};
-
-/** IOStream for stdout. */
-static IOStream _iostdout = {
-    methods: &file_methods,
-    data: (void*)2,
-    nofree: 1,
-};
-
-/** IOStream for stderr. */
-static IOStream _iostderr = {
-    methods: &file_methods,
-    data: (void*)3,
-    nofree: 1,
-};
-
-/** IOStream for stdin. */
-IOStream *iostdin = &_iostdin;
-
-/** IOStream for stdout. */
-IOStream *iostdout = &_iostdout;
-
-/** IOStream for stderr. */
-IOStream *iostderr = &_iostderr;
-
-/* Get the underlying FILE*.
- *
- * @param s file stream
- * @return the stream s wraps
- */
-static inline FILE *get_file(IOStream *s){
-     FILE *data = NULL;
-     switch((long)s->data){
-     case 1:
-         data = stdin;
-         break;
-     case 2:
-         data = stdout;
-         break;
-     case 3:
-         data = stderr;
-         break;
-     default:
-         data = (FILE*)s->data;
-         break;
-     }
-     return data;
-}
-
-/** Control buffering on the underlying stream, like setvbuf().
- *
- * @param io file stream
- * @param buf buffer
- * @param mode buffering mode (see man setvbuf())
- * @param size buffer size
- * @return 0 on success, non-zero otherwise
- */
-int file_stream_setvbuf(IOStream *io, char *buf, int mode, size_t size){
-    return setvbuf(get_file(io), buf, mode, size);
-}
-
-/** Write to the underlying stream using fwrite();
- *
- * @param stream input
- * @param buf where to put input
- * @param n number of bytes to write
- * @return number of bytes written
- */
-static int file_write(IOStream *s, const void *buf, size_t n){
-    return fwrite(buf, 1, n, get_file(s));
-}
-
-/** Read from the underlying stream using fread();
- *
- * @param stream input
- * @param buf where to put input
- * @param n number of bytes to read
- * @return number of bytes read
- */
-static int file_read(IOStream *s, void *buf, size_t n){
-    return fread(buf, 1, n, get_file(s));
-}
-
-/** Fush the underlying stream using fflush().
- *
- * @param s file stream
- * @return 0 on success, error code otherwise
- */
-static int file_flush(IOStream *s){
-    return fflush(get_file(s));
-}
-
-/** Check if a stream has an error.
- *
- * @param s file stream
- * @return 1 if has an error, 0 otherwise
- */
-static int file_error(IOStream *s){
-    return ferror(get_file(s));
-}
-
-/** Close a file stream.
- *
- * @param s file stream to close
- * @return result of the close
- */
-static int file_close(IOStream *s){
-    int result = 0;
-    result = fclose(get_file(s));
-    return result;
-}
-
-/** Free a file stream.
- *
- * @param s file stream
- */
-static void file_free(IOStream *s){
-    // Nothing extra to do - close did it all.
-}
-
-/** Create an IOStream for a stream.
- *
- * @param f stream to wrap
- * @return new IOStream using f for i/o
- */
-IOStream *file_stream_new(FILE *f){
-    IOStream *io = ALLOCATE(IOStream);
-    if(io){
-        io->methods = &file_methods;
-        io->data = (void*)f;
-    }
-    return io;
-}
-
-/** IOStream version of fopen().
- *
- * @param file name of the file to open
- * @param flags giving the mode to open in (as for fopen())
- * @return new stream for the open file, or 0 if failed
- */
-IOStream *file_stream_fopen(const char *file, const char *flags){
-    IOStream *io = 0;
-    FILE *fin = fopen(file, flags);
-    if(fin){
-        io = file_stream_new(fin);
-        if(!io){
-            fclose(fin);
-        }
-    }
-    return io;
-}
-
-/** IOStream version of fdopen().
- *
- * @param fd file descriptor
- * @param flags giving the mode to open in (as for fdopen())
- * @return new stream for the open file, or 0 if failed.  Always takes
- *         ownership of fd.
- */
-IOStream *file_stream_fdopen(int fd, const char *flags){
-    IOStream *io = 0;
-    FILE *fin = fdopen(fd, flags);
-    if(fin){
-        io = file_stream_new(fin);
-        if(!io){
-            fclose(fin);
-        }
-    }
-    return io;
-}
-#endif
diff --git a/tools/libxutil/file_stream.h b/tools/libxutil/file_stream.h
deleted file mode 100644 (file)
index f717656..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XUTIL_FILE_STREAM_H_
-#define _XUTIL_FILE_STREAM_H_
-
-#ifndef __KERNEL__
-#include "iostream.h"
-#include <stdio.h>
-
-extern IOStream *file_stream_new(FILE *f);
-extern IOStream *file_stream_fopen(const char *file, const char *flags);
-extern IOStream *file_stream_fdopen(int fd, const char *flags);
-extern IOStream get_stream_stdout(void);
-extern IOStream get_stream_stderr(void);
-extern IOStream get_stream_stdin(void);
-
-extern int file_stream_setvbuf(IOStream *io, char *buf, int mode, size_t size);
-#endif
-#endif /* !_XUTIL_FILE_STREAM_H_ */
diff --git a/tools/libxutil/gzip_stream.c b/tools/libxutil/gzip_stream.c
deleted file mode 100644 (file)
index ea14b82..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2003 Hewlett-Packard Company.
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/** @file
- * An IOStream implementation using zlib gzFile to provide
- * compression and decompression.
- */
-#ifndef __KERNEL__
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "zlib.h"
-
-#include "allocate.h"
-#include "gzip_stream.h"
-
-static int gzip_read(IOStream *s, void *buf, size_t n);
-static int gzip_write(IOStream *s, const void *buf, size_t n);
-static int gzip_error(IOStream *s);
-static int gzip_close(IOStream *s);
-static void gzip_free(IOStream *s);
-static int gzip_flush(IOStream *s);
-
-/** Methods used by a gzFile* IOStream. */
-static const IOMethods gzip_methods = {
-    read:  gzip_read,
-    write: gzip_write,
-    error: gzip_error,
-    close: gzip_close,
-    free:  gzip_free,
-    flush: gzip_flush,
-};
-
-/** Get the underlying gzFile*.
- * 
- * @param s gzip stream
- * @return the stream s wraps
- */
-static inline gzFile get_gzfile(IOStream *s){
-    return (gzFile)s->data;
-}
-
-/** Write to the underlying stream.
- *
- * @param stream destination
- * @param buf data
- * @param n number of bytes to write
- * @return number of bytes written
- */
-static int gzip_write(IOStream *s, const void *buf, size_t n){
-    return gzwrite(get_gzfile(s), (void*)buf, n);
-}
-
-/** Read from the underlying stream.
- *
- * @param stream input
- * @param buf where to put input
- * @param n number of bytes to read
- * @return number of bytes read
- */
-static int gzip_read(IOStream *s, void *buf, size_t n){
-    return gzread(get_gzfile(s), buf, n);
-}
-
-/** Flush the underlying stream.
- *
- * @param s gzip stream
- * @return 0 on success, error code otherwise
- */
-static int gzip_flush(IOStream *s){
-    //return gzflush(get_gzfile(s), Z_NO_FLUSH);
-    return gzflush(get_gzfile(s), Z_SYNC_FLUSH);
-    //return gzflush(get_gzfile(s), Z_FULL_FLUSH);
-}
-
-/** Check if a stream has an error.
- *
- * @param s gzip stream
- * @return 1 if has an error, 0 otherwise
- */
-static int gzip_error(IOStream *s){
-    int err;
-    gzFile *gz = get_gzfile(s);
-    gzerror(gz, &err);
-    return (err == Z_ERRNO ? 1 /* ferror(gzfile(gz)) */ : err);
-}
-
-/** Close a gzip stream.
- *
- * @param s gzip stream to close
- * @return result of the close
- */
-static int gzip_close(IOStream *s){
-    int result = 0;
-    result = gzclose(get_gzfile(s));
-    return result;
-}
-
-/** Free a gzip stream.
- *
- * @param s gzip stream
- */
-static void gzip_free(IOStream *s){
-    // Nothing to do - close did it all.
-}
-
-/** Create an IOStream for a gzip stream.
- *
- * @param f stream to wrap
- * @return new IOStream using f for i/o
- */
-IOStream *gzip_stream_new(gzFile *f){
-    IOStream *io = ALLOCATE(IOStream);
-    if(io){
-        io->methods = &gzip_methods;
-        io->data = (void*)f;
-    }
-    return io;
-}
-
-/** IOStream version of fopen().
- *
- * @param file name of the file to open
- * @param flags giving the mode to open in (as for fopen())
- * @return new stream for the open file, or NULL if failed
- */
-IOStream *gzip_stream_fopen(const char *file, const char *flags){
-    IOStream *io = NULL;
-    gzFile *fgz;
-    fgz = gzopen(file, flags);
-    if(fgz){
-        io = gzip_stream_new(fgz);
-        if(!io){
-            gzclose(fgz);
-        }
-    }
-    return io;
-}
-
-/** IOStream version of fdopen().
- *
- * @param fd file descriptor
- * @param flags giving the mode to open in (as for fdopen())
- * @return new stream for the open file, or NULL if failed.  Always takes
- *         ownership of fd.
- */
-IOStream *gzip_stream_fdopen(int fd, const char *flags){
-    IOStream *io = NULL;
-    gzFile *fgz;
-    fgz = gzdopen(fd, flags);
-    if(fgz){
-        io = gzip_stream_new(fgz);
-        if(!io)
-            gzclose(fgz);
-    }
-    return io;
-}
-#endif
diff --git a/tools/libxutil/gzip_stream.h b/tools/libxutil/gzip_stream.h
deleted file mode 100644 (file)
index fd28e39..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2003 Hewlett-Packard Company.
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XUTIL_GZIP_STREAM_H_
-#define _XUTIL_GZIP_STREAM_H_
-
-#ifndef __KERNEL__
-#include "iostream.h"
-#include "zlib.h"
-
-extern IOStream *gzip_stream_new(gzFile *f);
-extern IOStream *gzip_stream_fopen(const char *file, const char *flags);
-extern IOStream *gzip_stream_fdopen(int fd, const char *flags);
-#endif
-#endif /* !_XUTIL_GZIP_STREAM_H_ */
diff --git a/tools/libxutil/hash_table.c b/tools/libxutil/hash_table.c
deleted file mode 100644 (file)
index 13da946..0000000
+++ /dev/null
@@ -1,640 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifdef __KERNEL__
-#  include <linux/config.h>
-#  include <linux/module.h>
-#  include <linux/kernel.h>
-#  include <linux/errno.h>
-#else
-#  include <errno.h>
-#  include <stddef.h>
-#endif
-
-//#include <limits.h>
-
-#include "allocate.h"
-#include "hash_table.h"
-
-/** @file
- * Base support for hashtables.
- *
- * Hash codes are reduced modulo the number of buckets to index tables,
- * so there is no need for hash functions to limit the range of hashcodes.
- * In fact it is assumed that hashcodes do not change when the number of
- * buckets in the table changes.
- */
-
-/*==========================================================================*/
-/** Number of bits in half a word. */
-//#if __WORDSIZE == 64
-//#define HALF_WORD_BITS 32
-//#else
-#define HALF_WORD_BITS 16
-//#endif
-
-/** Mask for lo half of a word. On 32-bit this is 
- * (1<<16) - 1 = 65535 = 0xffff
- * It's 4294967295 = 0xffffffff on 64-bit.
- */
-#define LO_HALF_MASK ((1 << HALF_WORD_BITS) - 1)
-
-/** Get the lo half of a word. */
-#define LO_HALF(x) ((x) & LO_HALF_MASK)
-
-/** Get the hi half of a word. */
-#define HI_HALF(x) ((x) >> HALF_WORD_BITS)
-
-/** Do a full hash on both inputs, using DES-style non-linear scrambling.
- * Both inputs are replaced with the results of the hash.
- *
- * @param pleft input/output word
- * @param pright input/output word
- */
-void pseudo_des(unsigned long *pleft, unsigned long *pright){
-    // Bit-rich mixing constant.
-    static const unsigned long a_mixer[] = {
-        0xbaa96887L, 0x1e17d32cL, 0x03bcdc3cL, 0x0f33d1b2L, };
-
-    // Bit-rich mixing constant.
-    static const unsigned long b_mixer[] = {
-        0x4b0f3b58L, 0xe874f0c3L, 0x6955c5a6L, 0x55a7ca46L, };
-
-    // Number of iterations - must be 2 or 4.
-    static const int ncycle = 4;
-    //static const int ncycle = 2;
-
-    unsigned long left = *pleft, right = *pright;
-    unsigned long v, v_hi, v_lo;
-    int i;
-
-    for(i=0; i<ncycle; i++){
-        // Flip some bits in right to get v.
-        v = right;
-        v ^= a_mixer[i];
-        // Get lo and hi halves of v.
-        v_lo = LO_HALF(v);
-        v_hi = HI_HALF(v);
-        // Non-linear mix of the halves of v.
-        v = ((v_lo * v_lo) + ~(v_hi * v_hi));
-        // Swap the halves of v.
-        v = (HI_HALF(v) | (LO_HALF(v) << HALF_WORD_BITS));
-        // Flip some bits.
-        v ^= b_mixer[i];
-        // More non-linear mixing.
-        v += (v_lo * v_hi);
-        v ^= left;
-        left = right;
-        right = v;
-    }
-    *pleft = left;
-    *pright = right;
-}
-
-/** Hash a string.
- *
- * @param s input to hash
- * @return hashcode
- */
-Hashcode hash_string(char *s){
-    Hashcode h = 0;
-    if(s){
-        for( ; *s; s++){
-            h = hash_2ul(h, *s);
-        }
-    }
-    return h;
-}
-
-/** Get the bucket for a hashcode in a hash table.
- *
- * @param table to get bucket from
- * @param hashcode to get bucket for
- * @return bucket
- */
-inline HTBucket * get_bucket(HashTable *table, Hashcode hashcode){
-    return table->buckets + (hashcode % table->buckets_n);
-}
-
-/** Initialize a hash table.
- * Can be safely called more than once.
- *
- * @param table to initialize
- */
-void HashTable_init(HashTable *table){
-    int i;
-
-    if(!table->init_done){
-        table->init_done = 1;
-        table->next_id = 0;
-        for(i=0; i<table->buckets_n; i++){
-            HTBucket *bucket = get_bucket(table, i);
-            bucket->head = 0;
-            bucket->count = 0;
-        }
-        table->entry_count = 0;
-    }
-}
-
-/** Allocate a new hashtable.
- * If the number of buckets is not positive the default is used.
- * The number of buckets should usually be prime.
- *
- * @param buckets_n number of buckets
- * @return new hashtable or null
- */
-HashTable *HashTable_new(int buckets_n){
-    HashTable *z = ALLOCATE(HashTable);
-    if(!z) goto exit;
-    if(buckets_n <= 0){
-        buckets_n = HT_BUCKETS_N;
-    }
-    z->buckets = (HTBucket*)allocate(buckets_n * sizeof(HTBucket));
-    if(!z->buckets){
-        deallocate(z);
-        z = 0;
-        goto exit;
-    }
-    z->buckets_n = buckets_n;
-    HashTable_init(z);
-  exit:
-    return z;
-}
-
-/** Free a hashtable.
- * Any entries are removed and freed.
- *
- * @param h hashtable (ignored if null)
- */
-void HashTable_free(HashTable *h){
-    if(h){
-        HashTable_clear(h);
-        deallocate(h->buckets);
-        deallocate(h);
-    }
-}
-
-/** Push an entry on the list in the bucket for a given hashcode.
- *
- * @param table to add entry to
- * @param hashcode for the entry
- * @param entry to add
- */
-static inline void push_on_bucket(HashTable *table, Hashcode hashcode,
-                                 HTEntry *entry){
-    HTBucket *bucket;
-    HTEntry *old_head;
-
-    bucket = get_bucket(table, hashcode);
-    old_head = bucket->head;
-    bucket->count++;
-    bucket->head = entry;
-    entry->next = old_head;
-}
-
-/** Change the number of buckets in a hashtable.
- * No-op if the number of buckets is not positive.
- * Existing entries are reallocated to buckets based on their hashcodes.
- * The table is unmodified if the number of buckets cannot be changed.
- *
- * @param table hashtable
- * @param buckets_n new number of buckets
- * @return 0 on success, error code otherwise
- */
-int HashTable_set_buckets_n(HashTable *table, int buckets_n){
-    int err = 0;
-    HTBucket *old_buckets = table->buckets;
-    int old_buckets_n = table->buckets_n;
-    int i;
-
-    if(buckets_n <= 0){
-        err = -EINVAL;
-        goto exit;
-    }
-    table->buckets = (HTBucket*)allocate(buckets_n * sizeof(HTBucket));
-    if(!table->buckets){
-        err = -ENOMEM;
-        table->buckets = old_buckets;
-        goto exit;
-    }
-    table->buckets_n = buckets_n;
-    for(i=0; i<old_buckets_n; i++){
-        HTBucket *bucket = old_buckets + i;
-        HTEntry *entry, *next;
-        for(entry = bucket->head; entry; entry = next){
-            next = entry->next;
-            push_on_bucket(table, entry->hashcode, entry);
-        }
-    }
-    deallocate(old_buckets);
-  exit:
-    return err;
-}
-
-/** Adjust the number of buckets so the table is neither too full nor too empty.
- * The table is unmodified if adjusting fails.
- *
- * @param table hash table
- * @param buckets_min minimum number of buckets (use default if 0 or negative)
- * @return 0 on success, error code otherwise
- */
-int HashTable_adjust(HashTable *table, int buckets_min){
-    int buckets_n = 0;
-    int err = 0;
-    if(buckets_min <= 0) buckets_min = HT_BUCKETS_N;
-    if(table->entry_count >= table->buckets_n){
-        // The table is dense - expand it.
-        buckets_n = 2 * table->buckets_n;
-    } else if((table->buckets_n > buckets_min) &&
-              (4 * table->entry_count < table->buckets_n)){
-        // The table is more than minimum size and sparse - shrink it.
-        buckets_n = 2 * table->entry_count;
-        if(buckets_n < buckets_min) buckets_n = buckets_min;
-    }
-    if(buckets_n){
-        err = HashTable_set_buckets_n(table, buckets_n);
-    }
-    return err;
-}
-
-/** Allocate a new entry for a given value.
- *
- * @param value to put in the entry
- * @return entry, or 0 on failure
- */
-HTEntry * HTEntry_new(Hashcode hashcode, void *key, void *value){
-    HTEntry *z = ALLOCATE(HTEntry);
-    if(z){
-        z->hashcode = hashcode;
-        z->key = key;
-        z->value = value;
-    }
-    return z;
-}
-
-/** Free an entry.
- *
- * @param z entry to free
- */
-inline void HTEntry_free(HTEntry *z){
-    if(z){
-        deallocate(z);
-    }
-}
-
-/** Free an entry in a hashtable.
- * The table's entry_free_fn is used is defined, otherwise 
- * the HTEntry itself is freed.
- *
- * @param table hashtable
- * @param entry to free
- */
-inline void HashTable_free_entry(HashTable *table, HTEntry *entry){
-    if(!entry)return;
-    if(table && table->entry_free_fn){
-        table->entry_free_fn(table, entry);
-    } else {
-        HTEntry_free(entry);
-    }
-}
-
-/** Get the first entry satisfying a test from the bucket for the
- * given hashcode.
- *
- * @param table to look in
- * @param hashcode indicates the bucket
- * @param test_fn test to apply to elements
- * @param arg first argument to calls to test_fn
- * @return entry found, or 0
- */
-inline HTEntry * HashTable_find_entry(HashTable *table, Hashcode hashcode,
-                                     TableTestFn *test_fn, TableArg arg){
-    HTBucket *bucket;
-    HTEntry *entry = 0;
-    HTEntry *next;
-
-    bucket = get_bucket(table, hashcode);
-    for(entry = bucket->head; entry; entry = next){
-        next = entry->next;
-        if(test_fn(arg, table, entry)){
-            break;
-        }
-    }
-    return entry;
-}
-
-/** Test hashtable keys for equality.
- * Uses the table's key_equal_fn if defined, otherwise pointer equality.
- *
- * @param key1 key to compare
- * @param key2 key to compare
- * @return 1 if equal, 0 otherwise
- */
-inline int HashTable_key_equal(HashTable *table, void *key1, void *key2){
-    return (table->key_equal_fn ? table->key_equal_fn(key1, key2) : key1==key2);
-}
-
-/** Compute the hashcode of a hashtable key.
- * The table's key_hash_fn is used if defined, otherwise the address of
- * the key is hashed.
- *
- * @param table hashtable
- * @param key to hash
- * @return hashcode
- */
-inline Hashcode HashTable_key_hash(HashTable *table, void *key){
-    return (table->key_hash_fn ? table->key_hash_fn(key) : hash_ul((unsigned long)key));
-}
-
-/** Test if an entry has a given key.
- *
- * @param arg containing key to test for
- * @param table the entry is in
- * @param entry to test
- * @return 1 if the entry has the key, 0 otherwise
- */
-static inline int has_key(TableArg arg, HashTable *table, HTEntry *entry){
-    return HashTable_key_equal(table, arg.ptr, entry->key);
-}
-
-/** Get an entry with a given key.
- *
- * @param table to search
- * @param key to look for
- * @return entry if found, null otherwise
- */
-#if 0
-inline HTEntry * HashTable_get_entry(HashTable *table, void *key){
-    TableArg arg = { ptr: key };
-    return HashTable_find_entry(table, HashTable_key_hash(table, key), has_key, arg);
-}
-#else
-inline HTEntry * HashTable_get_entry(HashTable *table, void *key){
-    Hashcode hashcode;
-    HTBucket *bucket;
-    HTEntry *entry = 0;
-    HTEntry *next;
-
-    hashcode = HashTable_key_hash(table, key);
-    bucket = get_bucket(table, hashcode);
-    for(entry = bucket->head; entry; entry = next){
-        next = entry->next;
-        if(HashTable_key_equal(table, key, entry->key)){
-            break;
-        }
-    }
-    return entry;
-}
-#endif
-
-/** Get the value of an entry with a given key.
- *
- * @param table to search
- * @param key to look for
- * @return value if an entry was found, null otherwise
- */
-inline void * HashTable_get(HashTable *table, void *key){
-    HTEntry *entry = HashTable_get_entry(table, key);
-    return (entry ? entry->value : 0);
-}
-
-/** Print the buckets in a table.
- *
- * @param table to print
- */
-void show_buckets(HashTable *table, IOStream *io){
-    int i,j ;
-    IOStream_print(io, "entry_count=%d buckets_n=%d\n", table->entry_count, table->buckets_n);
-    for(i=0; i<table->buckets_n; i++){
-        if(0 || table->buckets[i].count>0){
-            IOStream_print(io, "bucket %3d %3d %10p ", i,
-                        table->buckets[i].count,
-                        table->buckets[i].head);
-            for(j = table->buckets[i].count; j>0; j--){
-                IOStream_print(io, "+");
-            }
-            IOStream_print(io, "\n");
-        }
-    }
-    HashTable_print(table, io); 
-}
-    
-/** Print an entry in a table.
- *
- * @param entry to print
- * @param arg a pointer to an IOStream to print to
- * @return 0
- */
-static int print_entry(TableArg arg, HashTable *table, HTEntry *entry){
-    IOStream *io = (IOStream*)arg.ptr;
-    IOStream_print(io, " b=%4lx h=%08lx i=%08lx |-> e=%8p k=%8p v=%8p\n",
-                entry->hashcode % table->buckets_n,
-                entry->hashcode,
-                entry->index,
-                entry, entry->key, entry->value);
-    return 0;
-}
-
-/** Print a hash table.
- *
- * @param table to print
- */
-void HashTable_print(HashTable *table, IOStream *io){
-    IOStream_print(io, "{\n");
-    HashTable_map(table, print_entry, (TableArg){ ptr: io });
-    IOStream_print(io, "}\n");
-}
-/*==========================================================================*/
-
-/** Get the next entry id to use for a table.
- *
- * @param table hash table
- * @return non-zero entry id
- */
-static inline unsigned long get_next_id(HashTable *table){
-    unsigned long id;
-
-    if(table->next_id == 0){
-        table->next_id = 1;
-    }
-    id = table->next_id++;
-    return id;
-}
-
-/** Add an entry to the bucket for the
- * given hashcode.
- *
- * @param table to insert in
- * @param hashcode indicates the bucket
- * @param key to add an entry for
- * @param value to add an entry for
- * @return entry on success, 0 on failure
- */
-inline HTEntry * HashTable_add_entry(HashTable *table, Hashcode hashcode, void *key, void *value){
-    HTEntry *entry = HTEntry_new(hashcode, key, value);
-    if(entry){
-        entry->index = get_next_id(table);
-        push_on_bucket(table, hashcode, entry);
-        table->entry_count++;
-    }
-    return entry;
-}
-
-/** Move the front entry for a bucket to the correct point in the bucket order as
- * defined by the order function. If this is called every time a new entry is added
- * the bucket will be maintained in sorted order.
- *
- * @param table to modify
- * @param hashcode indicates the bucket
- * @param order entry comparison function
- * @return 0 if an entry was moved, 1 if not
- */
-int HashTable_order_bucket(HashTable *table, Hashcode hashcode, TableOrderFn *order){
-    HTEntry *new_entry = NULL, *prev = NULL, *entry = NULL;
-    HTBucket *bucket;
-    int err = 1;
-
-    bucket = get_bucket(table, hashcode);
-    new_entry = bucket->head;
-    if(!new_entry || !new_entry->next) goto exit;
-    for(entry = new_entry->next; entry; prev = entry, entry = entry->next){
-        if(order(new_entry, entry) <= 0) break;
-    }
-    if(prev){
-        err = 0;
-        bucket->head = new_entry->next; 
-        new_entry->next = entry;
-        prev->next = new_entry;
-    }
-  exit:
-    return err;
-}
-
-/** Add an entry to a hashtable.
- * The entry is added to the bucket for its key's hashcode.
- *
- * @param table to insert in
- * @param key to add an entry for
- * @param value to add an entry for
- * @return entry on success, 0 on failure
- */
-inline HTEntry * HashTable_add(HashTable *table, void *key, void *value){
-    return HashTable_add_entry(table, HashTable_key_hash(table, key), key, value);
-}
-
-
-/** Remove entries satisfying a test from the bucket for the
- * given hashcode. 
- *
- * @param table to remove from
- * @param hashcode indicates the bucket
- * @param test_fn test to apply to elements
- * @param arg first argument to calls to test_fn
- * @return number of entries removed
- */
-inline int HashTable_remove_entry(HashTable *table, Hashcode hashcode,
-                                 TableTestFn *test_fn, TableArg arg){
-    HTBucket *bucket;
-    HTEntry *entry, *prev = 0, *next;
-    int removed_count = 0;
-
-    bucket = get_bucket(table, hashcode);
-    for(entry = bucket->head; entry; entry = next){
-        next = entry->next;
-        if(test_fn(arg, table, entry)){
-            if(prev){
-                prev->next = next;
-            } else {
-                bucket->head = next;
-            }
-            bucket->count--;
-            table->entry_count--;
-            removed_count++;
-            HashTable_free_entry(table, entry);
-            entry = 0;
-        }
-        prev = entry;
-    }
-    return removed_count;
-}
-
-/** Remove entries with a given key. 
- *
- * @param table to remove from
- * @param key of entries to remove
- * @return number of entries removed
- */
-inline int HashTable_remove(HashTable *table, void *key){
-#if 1
-    Hashcode hashcode;
-    HTBucket *bucket;
-    HTEntry *entry, *prev = 0, *next;
-    int removed_count = 0;
-
-    hashcode = HashTable_key_hash(table, key);
-    bucket = get_bucket(table, hashcode);
-    for(entry = bucket->head; entry; entry = next){
-        next = entry->next;
-        if(HashTable_key_equal(table, key, entry->key)){
-            if(prev){
-                prev->next = next;
-            } else {
-                bucket->head = next;
-            }
-            bucket->count--;
-            table->entry_count--;
-            removed_count++;
-            HashTable_free_entry(table, entry);
-            entry = 0;
-        }
-        prev = entry;
-    }
-    return removed_count;
-#else
-    return HashTable_remove_entry(table, HashTable_key_hash(table, key),
-                                 has_key, (TableArg){ ptr: key});
-#endif
-}
-
-/** Remove (and free) all the entries in a bucket.
- *
- * @param bucket to clear
- */
-static inline void bucket_clear(HashTable *table, HTBucket *bucket){
-    HTEntry *entry, *next;
-
-    for(entry = bucket->head; entry; entry = next){
-        next = entry->next;
-        HashTable_free_entry(table, entry);
-    }
-    bucket->head = 0;
-    table->entry_count -= bucket->count;
-    bucket->count = 0;
-}
-
-/** Remove (and free) all the entries in a table.
- *
- * @param table to clear
- */
-void HashTable_clear(HashTable *table){
-    int i, n = table->buckets_n;
-
-    for(i=0; i<n; i++){
-        bucket_clear(table, table->buckets + i);
-    }
-}
diff --git a/tools/libxutil/hash_table.h b/tools/libxutil/hash_table.h
deleted file mode 100644 (file)
index 6608b49..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XUTIL_HASH_TABLE_H_
-#define _XUTIL_HASH_TABLE_H_
-
-#include "iostream.h"
-
-typedef unsigned long Hashcode;
-
-/** Type used to pass parameters to table functions. */
-typedef union TableArg {
-    unsigned long ul;
-    void *ptr;
-} TableArg;
-
-/** An entry in a bucket list. */
-typedef struct HTEntry {
-    /** Hashcode of the entry's key. */
-    Hashcode hashcode;
-    /** Identifier for this entry in the table. */
-    int index;
-    /** The key for this entry. */
-    void *key;
-    /** The value in this entry. */
-    void *value;
-    /** The next entry in the list. */
-    struct HTEntry *next;
-} HTEntry;
-
-/** A bucket in a rule table. */
-typedef struct HTBucket {
-    /** Number of entries in the bucket. */
-    int count;
-    /** First entry in the bucket (may be null). */
-    HTEntry *head;
-} HTBucket;
-
-/** Default number of buckets in a hash table.
- * You want enough buckets so the lists in the buckets will typically be short.
- * It's a good idea if this is prime, since that will help to spread hashcodes
- * around the table.
- */
-//#define HT_BUCKETS_N 1
-//#define HT_BUCKETS_N 3
-//#define HT_BUCKETS_N 7
-//#define HT_BUCKETS_N 17
-//#define HT_BUCKETS_N 97
-//#define HT_BUCKETS_N 211
-//#define HT_BUCKETS_N 401
-#define HT_BUCKETS_N 1021
-
-typedef struct HashTable HashTable;
-
-/** Type for a function used to select table entries. */
-typedef int TableTestFn(TableArg arg, HashTable *table, HTEntry *entry);
-
-/** Type for a function to map over table entries. */
-typedef int TableMapFn(TableArg arg, HashTable *table, HTEntry *entry);
-
-/** Type for a function to free table entries. */
-typedef void TableFreeFn(HashTable *table, HTEntry *entry);
-
-/** Type for a function to hash table keys. */
-typedef Hashcode TableHashFn(void *key);
-
-/** Type for a function to test table keys for equality. */
-typedef int TableEqualFn(void *key1, void *key2);
-
-/** Type for a function to order table entries. */
-typedef int TableOrderFn(HTEntry *e1, HTEntry *e2);
-
-/** General hash table.
- * A hash table with a list in each bucket.
- * Functions can be supplied for freeing entries, hashing keys, and comparing keys.
- * These all default to 0, when default behaviour treating keys as integers is used.
- */
-struct HashTable {
-    /** Flag indicating whether the table has been initialised. */
-    int init_done;
-    /** Next value for the id field in inserted rules. */
-    unsigned long next_id;
-    /** Number of buckets in the bucket array. */
-    int buckets_n;
-    /** Array of buckets, each with its own list. */
-    HTBucket *buckets;
-    /** Number of entries in the table. */
-    int entry_count;
-    /** Function to free keys and values in entries. */
-    TableFreeFn *entry_free_fn;
-    /** Function to hash keys. */
-    TableHashFn *key_hash_fn;
-    /** Function to compare keys for equality. */
-    TableEqualFn *key_equal_fn;
-    /** Place for the user of the table to hang extra data. */
-    void *user_data;
-};
-
-extern HashTable *HashTable_new(int bucket_n);
-extern void HashTable_free(HashTable *table);
-extern HTEntry * HTEntry_new(Hashcode hashcode, void *key, void *value);
-extern void HTEntry_free(HTEntry *entry);
-extern int HashTable_set_bucket_n(HashTable *table, int bucket_n);
-extern void HashTable_clear(HashTable *table);
-extern HTEntry * HashTable_add_entry(HashTable *table, Hashcode hashcode, void *key, void *value);
-extern HTEntry * HashTable_get_entry(HashTable *table, void *key);
-extern HTEntry * HashTable_add(HashTable *table, void *key, void *value);
-extern void * HashTable_get(HashTable *table, void *key);
-extern int HashTable_remove(HashTable *table, void *key);
-extern HTEntry * HashTable_find_entry(HashTable *table, Hashcode hashcode,
-                                      TableTestFn *test_fn, TableArg arg);
-extern int HashTable_remove_entry(HashTable *table, Hashcode hashcode,
-                                   TableTestFn *test_fn, TableArg arg);
-//extern int HashTable_map(HashTable *table, TableMapFn *map_fn, TableArg arg);
-extern void HashTable_print(HashTable *table, IOStream *out);
-extern int HashTable_set_buckets_n(HashTable *table, int buckets_n);
-extern int HashTable_adjust(HashTable *table, int buckets_min);
-extern void pseudo_des(unsigned long *pleft, unsigned long *pright);
-extern Hashcode hash_string(char *s);
-
-extern int HashTable_order_bucket(HashTable *table, Hashcode hashcode, TableOrderFn *order);
-
-/** Control whether to use hashing based on DES or simple
- * hashing. DES hashing is `more random' but much more expensive.
- */
-#define HASH_PSEUDO_DES 0
-
-/** Hash a long using a quick and dirty linear congruential random number generator.
- *  See `Numerical Recipes in C', Chapter 7, "An Even Quicker Generator".
- *
- * @param a value to hash
- * @return hashed input
- */
-static inline unsigned long lcrng_hash(unsigned long a){
-    return (1664525L * a + 1013904223L);
-}
-
-/** Hash an unsigned long.
- *
- * @param a input to hash
- * @return hashcode
- */
-static inline Hashcode hash_ul(unsigned long a){
-#if HASH_PSEUDO_DES
-    unsigned long left = a;
-    unsigned long right = 0L;
-    pseudo_des(&left, &right);
-    return right;
-#else
-    a = lcrng_hash(a);
-    a = lcrng_hash(a);
-    return a;
-#endif
-}
-
-/** Hash two unsigned longs together.
- *
- * @param a input to hash
- * @param b input to hash
- * @return hashcode
- */
-static inline Hashcode hash_2ul(unsigned long a, unsigned long b){
-#if HASH_PSEUDO_DES
-    unsigned long left = a;
-    unsigned long right = b;
-    pseudo_des(&left, &right);
-    return right;
-#else
-    a = lcrng_hash(a);
-    a ^= b;
-    a = lcrng_hash(a);
-    return a;
-#endif
-}
-
-/** Hash a hashcode and an unsigned long together.
- *
- * @param a input hashcode
- * @param b input to hash
- * @return hashcode
- */
-static inline Hashcode hash_hul(Hashcode a, unsigned long b){
-#if HASH_PSEUDO_DES
-    unsigned long left = a;
-    unsigned long right = b;
-    pseudo_des(&left, &right);
-    return right;
-#else
-    a ^= b;
-    a = lcrng_hash(a);
-    return a;
-#endif
-}
-
-/** Macro to declare variables for HashTable_for_each() to use.
- *
- * @param entry variable that is set to entries in the table
- */
-#define HashTable_for_decl(entry) \
-  HashTable *_var_table; \
-  HTBucket *_var_bucket; \
-  HTBucket *_var_end; \
-  HTEntry *_var_next; \
-  HTEntry *entry
-
-/** Macro to iterate over the entries in a hashtable.
- * Must be in a scope where HashTable_for_decl() has been used to declare
- * variables for it to use.
- * The variable 'entry' is iterated over entries in the table.
- * The code produced is syntactically a loop, so it must be followed by
- * a loop body, typically some statements in braces:
- * HashTable_for_each(entry, table){ ...loop body... }
- *
- * HashTable_for_each() and HashTable_for_decl() cannot be used for nested
- * loops as variables will clash.
- *
- * @note The simplest way to code a direct loop over the entries in a hashtable
- * is to use a loop over the buckets, with a nested loop over the entries
- * in a bucket. Using this approach in a macro means the macro contains
- * an opening brace, and calls to it must be followed by 2 braces!
- * To avoid this the code has been restructured so that it is a for loop.
- * So that statements could be used in the test expression of the for loop,
- * we have used the gcc statement expression extension ({ ... }).
- *
- * @param entry variable to iterate over the entries
- * @param table to iterate over (non-null)
- */
-#define HashTable_for_each(entry, table) \
-  _var_table = table; \
-  _var_bucket = _var_table->buckets; \
-  _var_end = _var_bucket + _var_table->buckets_n; \
-  for(entry=0, _var_next=0; \
-      ({ if(_var_next){ \
-             entry = _var_next; \
-             _var_next = entry->next; \
-          } else { \
-             while(_var_bucket < _var_end){ \
-                 entry = _var_bucket->head; \
-                 _var_bucket++; \
-                 if(entry){ \
-                      _var_next = entry->next; \
-                      break; \
-                 } \
-             } \
-          }; \
-         entry; }); \
-      entry = _var_next )
-
-/** Map a function over the entries in a table.
- * Mapping stops when the function returns a non-zero value.
- * Uses the gcc statement expression extension ({ ... }).
- *
- * @param table to map over
- * @param fn function to apply to entries
- * @param arg first argument to call the function with
- * @return 0 if fn always returned 0, first non-zero value otherwise
- */
-#define HashTable_map(table, fn, arg) \
-  ({ HashTable_for_decl(_var_entry); \
-    TableArg _var_arg = arg; \
-    int _var_value = 0; \
-    HashTable_for_each(_var_entry, table){ \
-        if((_var_value = fn(_var_arg, _var_table, _var_entry))) break; \
-    } \
-    _var_value; })
-
-/** Cast x to the type for a key or value in a hash table.
- * This avoids compiler warnings when using short integers
- * as keys or values (especially on 64-bit platforms).
- */
-#define HKEY(x) ((void*)(unsigned long)(x))
-
-/** Cast x from the type for a key or value in a hash table.
- * to an unsigned long. This avoids compiler warnings when using
- * short integers as keys or values (especially on 64-bit platforms).
- */
-#define HVAL(x) ((unsigned long)(x))
-
-#endif /* !_XUTIL_HASH_TABLE_H_ */
diff --git a/tools/libxutil/iostream.c b/tools/libxutil/iostream.c
deleted file mode 100644 (file)
index 39a6217..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "iostream.h"
-#include "sys_string.h"
-
-/** Print on a stream, like vfprintf().
- *
- * @param stream to print to
- * @param format for the print (as fprintf())
- * @param args arguments to print
- * @return result code from the print
- */
-int IOStream_vprint(IOStream *stream, const char *format, va_list args){
-  char buffer[1024];
-  int k = sizeof(buffer), n;
-
-  n = vsnprintf(buffer, k, (char*)format, args);
-  if(n < 0 || n > k ){
-      n = k;
-  }
-  n = IOStream_write(stream, buffer, n);
-  return n;
-}
-
-/** Print on a stream, like fprintf().
- *
- * @param stream to print to
- * @param format for the print (as fprintf())
- * @return result code from the print
- */
-int IOStream_print(IOStream *stream, const char *format, ...){
-  va_list args;
-  int result = -1;
-
-  va_start(args, format);
-  result = IOStream_vprint(stream, format, args);
-  va_end(args);
-  return result;
-}
diff --git a/tools/libxutil/iostream.h b/tools/libxutil/iostream.h
deleted file mode 100644 (file)
index f41ca56..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XUTIL_IOSTREAM_H_
-#define _XUTIL_IOSTREAM_H_
-
-#include <stdarg.h>
-
-#ifdef __KERNEL__
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#else
-#include <errno.h>
-#include <stdint.h>
-#include <stddef.h>
-#endif
-
-#include "allocate.h"
-
-/** End of input return value (for getc). */
-#define IOSTREAM_EOF -1
-
-/** An input/output abstraction.
- */
-typedef struct IOStream IOStream;
-
-/** Record of the functions to use for operations on an
- * IOStream implementation.
- */
-typedef struct IOMethods {
-    /** Read function.  Called with the user data, buffer to read into
-     * and number of bytes to read.  Must return number of bytes read
-     * on success, less than zero on error.
-     */
-    int (*read)(IOStream *stream, void *buf, size_t n);
-
-    /** Write function. Called with user data, buffer to write and
-     * number of bytes to write. Must return number of bytes written on
-     * success, less than zero otherwise.
-     */
-    int (*write)(IOStream *stream, const void *buf, size_t n);
-
-    int (*flush)(IOStream *s);
-
-    int (*error)(IOStream *s);
-
-    int (*close)(IOStream *s);
-
-    void (*free)(IOStream *s);
-
-    void (*lock)(IOStream *s);
-    void (*unlock)(IOStream *s);
-
-} IOMethods;
-
-/** Abstract i/o object.
- */
-struct IOStream {
-    /** Methods to use to implement operations. */
-    const IOMethods *methods;
-    /** Private state for the implementation. */
-    const void *data;
-    /** Flag indicating whether the stream is closed. */
-    int closed;
-    /** Number of bytes written. */
-    int written;
-    /** Number of bytes read. */
-    int read;
-    /** Flag indicating whether not to free when closed. */
-    int nofree;
-};
-
-
-/** IOStream version of stdin. */
-extern IOStream *iostdin;
-
-/** IOStream version of stdout, */
-extern IOStream *iostdout;
-
-/** IOStream version of stderr. */
-extern IOStream *iostderr;
-
-extern int IOStream_print(IOStream *io, const char *format, ...);
-extern int IOStream_vprint(IOStream *io, const char *format, va_list args);
-
-/** Read from a stream.
- *
- * @param stream input
- * @param buf where to put input
- * @param n number of bytes to read
- * @return if ok, number of bytes read, otherwise negative error code
- */
-static inline int IOStream_read(IOStream *stream, void *buf, size_t n){
-    int result;
-    if(stream->closed){
-        result = -EIO;
-        goto exit;
-    }
-    if(!stream->methods || !stream->methods->read){
-        result = -EINVAL;
-        goto exit;
-    }
-    result = (stream->methods->read)(stream, buf, n);
-    if(result > 0){
-        stream->read += result;
-    }
-  exit:
-    return result;
-}
-
-/** Write to a stream.
- *
- * @param stream input
- * @param buf where to put input
- * @param n number of bytes to write
- * @return if ok, number of bytes written, otherwise negative error code
- */
-static inline int IOStream_write(IOStream *stream, const void *buf, size_t n){
-    int result;
-    if(stream->closed){
-        result = -EIO;
-        goto exit;
-    }
-    if(!stream->methods || !stream->methods->write){
-        result = -EINVAL;
-        goto exit;
-    }
-    result = (stream->methods->write)(stream, buf, n);
-    if(result > 0){
-        stream->written += result;
-    }
-  exit:
-    return result;
-}
-
-/** Flush the stream.
- *
- * @param stream stream
- * @return 0 on success, negative error code otherwise
- */
-static inline int IOStream_flush(IOStream *stream){
-    int result = 0;
-    if(stream->closed){
-        result = -EIO;
-    } else if(stream->methods->flush){
-        result = (stream->methods->flush)(stream);
-    }
-    return result;
-}
-
-/** Check whether the stream has an error.
- *
- * @param stream to check
- * @return 1 for error, 0 otherwise
- */
-static inline int IOStream_error(IOStream *stream){
-    int err = 0;
-    if(stream->methods && stream->methods->error){
-       err = (stream->methods->error)(stream);
-    }
-    return err;
-}
-
-/** Close the stream.
- *
- * @param stream to close
- * @return 0 on success, negative error code otherwise
- */
-static inline int IOStream_close(IOStream *stream){
-    int err = 0;
-    if(!stream || stream->closed){
-        err = -EIO;
-        goto exit;
-    }
-    if(stream->methods && stream->methods->close){
-        err = (stream->methods->close)(stream);
-        stream->closed = 1;
-    }
-    if(stream->nofree) goto exit;
-    if(stream->methods && stream->methods->free){
-        (stream->methods->free)(stream);
-    }
-    *stream = (IOStream){};
-    deallocate(stream);
-  exit:
-    return err;
-}
-
-/** Test if the stream has been closed.
- *
- * @param stream to check
- * @return 1 if closed, 0 otherwise
- */
-static inline int IOStream_is_closed(IOStream *stream){
-    return stream->closed;
-}
-
-/** Print a character to a stream, like fputc().
- *
- * @param stream to print to
- * @param c character to print
- * @return result code from the print
- */
-static inline int IOStream_putc(IOStream *stream, int c){
-    int err;
-    unsigned char b = (unsigned char)c;
-    err = IOStream_write(stream, &b, 1);
-    if(err < 1){
-        err = IOSTREAM_EOF;
-    } else {
-        err = b;
-    }
-    return err;
-}
-
-/** Read from a stream, like fgetc().
- *
- * @param stream to read from
- * @return IOSTREAM_EOF on error, character read otherwise
- */
-static inline int IOStream_getc(IOStream *stream){
-    int err, rc;
-    unsigned char b;
-
-    err = IOStream_read(stream, &b, 1);
-    if(err < 1){
-        rc = IOSTREAM_EOF;
-    } else {
-        rc = b;
-    }
-    return rc;
-}
-
-/** Get number of bytes read.
- *
- * @param stream to get from
- * @return number of bytes read
- */
-static inline int IOStream_get_read(IOStream *stream){
-    return stream->read;
-}
-
-/** Get number of bytes written.
- *
- * @param stream to get from
- * @return number of bytes written
- */
-static inline int IOStream_get_written(IOStream *stream){
-    return stream->written;
-}
-
-
-#endif /* ! _XUTIL_IOSTREAM_H_ */
diff --git a/tools/libxutil/kernel_stream.c b/tools/libxutil/kernel_stream.c
deleted file mode 100644 (file)
index 3c6b552..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/** @file
- * An IOStream implementation using printk() for output.
- * Input is not implemented.
- */
-#ifdef __KERNEL__
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-
-#include "kernel_stream.h"
-#include "allocate.h"
-
-/** Number of characters in the output buffer.
- * The kernel uses 1024 for printk, so that should suffice.
- */
-#define BUF_N 1024
-
-/** State for a kernel stream. */
-typedef struct KernelData {
-    /** Stream lock. We need a lock to serialize access to the stream. */
-    spinlock_t lock;
-    /** Saved flags for locking. */
-    unsigned long flags;
-    /** Size of the output buffer. */
-    int buf_n;
-    /** Output buffer. */
-    char buf[BUF_N];
-} KernelData;
-
-static int kernel_write(IOStream *s, const void *msg, size_t n);
-static void kernel_free(IOStream *s);
-static void kernel_stream_lock(IOStream *s);
-static void kernel_stream_unlock(IOStream *s);
-
-/** Methods for a kernel stream. Output only. */
-static const IOMethods kernel_methods = {
-    write:  kernel_write,
-    free:   kernel_free,
-    lock:   kernel_stream_lock,
-    unlock: kernel_stream_unlock,
-};
-
-/** Shared state for kernel streams.
- * All implementations write using printk, so we can use
- * shared state and avoid allocating it.
- */
-static const KernelData kernel_data = {
-    lock:  SPIN_LOCK_UNLOCKED,
-    flags: 0,
-    buf_n: BUF_N,
-};
-
-/** Stream for kernel printk. */
-static IOStream iokernel = {
-    methods: &kernel_methods,
-    data:    &kernel_data,
-    nofree:  1,
-};
-
-/** Stream for kernel printk. */
-IOStream *iostdout = &iokernel;
-
-/** Stream for kernel printk. */
-IOStream *iostdin = &iokernel;
-
-/** Stream for kernel printk. */
-IOStream *iostderr = &iokernel;
-
-/** Get an output-only stream implementation using
- * printk(). The stream uses static storage, and must not be freed.
- *
- * @return kernel stream
- */
-IOStream get_stream_kernel(void){
-    return iokernel;
-}
-
-/** Obtain the lock on the stream state.
- *
- * @param kdata stream state
- */
-static inline void KernelData_lock(KernelData *kdata){
-    spin_lock_irqsave(&kdata->lock, kdata->flags);
-}
-
-/** Release the lock on the stream state.
- *
- * @param kdata stream state
- */
-static inline void KernelData_unlock(KernelData *kdata){
-    spin_unlock_irqrestore(&kdata->lock, kdata->flags);
-}
-
-/** Get the stream state.
- *
- * @param s kernel stream
- * @return stream state
- */
-static inline KernelData *get_kernel_data(IOStream *s){
-    return (KernelData*)s->data;
-}
-
-/** Obtain the lock on the stream state.
- *
- * @param s stream
- */
-void kernel_stream_lock(IOStream *s){
-    KernelData_lock(get_kernel_data(s));
-}
-
-/** Release the lock on the stream state.
- *
- * @param s stream
- */
-void kernel_stream_unlock(IOStream *s){
-    KernelData_unlock(get_kernel_data(s));
-}
-
-/** Write to a kernel stream.
- *
- * @param stream kernel stream
- * @param format print format
- * @param args print arguments
- * @return result of the print
- */
-static int kernel_write(IOStream *stream, const void *buf, size_t n){
-    KernelData *kdata = get_kernel_data(stream);
-    int k;
-    k = kdata->buf_n - 1;
-    if(n < k) k = n;
-    memcpy(kdata->buf, buf, k);
-    kdata->buf[k] = '\0';
-    printk(kdata->buf);
-    return k;
-}
-
-/** Free a kernel stream.
- * Frees the internal state of the stream.
- * Do not call this unless the stream was dynamically allocated.
- * Do not call this on a stream returned from get_stream_kernel().
- *
- * @param io stream to free
- */
-static void kernel_free(IOStream *io){
-    KernelData *kdata;
-    if(io == &iokernel) return;
-    kdata = get_kernel_data(io);
-    memset(kdata, 0, sizeof(*kdata));
-    deallocate(kdata);
-}
-#endif /* __KERNEL__ */
-
-
-
-
diff --git a/tools/libxutil/kernel_stream.h b/tools/libxutil/kernel_stream.h
deleted file mode 100644 (file)
index 0f18058..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XUTIL_KERNEL_STREAM_H_
-#define _XUTIL_KERNEL_STREAM_H_
-
-#ifdef __KERNEL__
-#include "iostream.h"
-
-extern IOStream get_stream_kernel(void);
-#define get_stream_stdout get_stream_kernel
-
-#endif /* __KERNEL__ */
-#endif /* !_XUTIL_KERNEL_STREAM_H_ */
diff --git a/tools/libxutil/lexis.c b/tools/libxutil/lexis.c
deleted file mode 100644 (file)
index d3441f0..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-/** @file
- * Lexical analysis.
- */
-
-#include "sys_string.h"
-#include "lexis.h"
-#include <errno.h>
-
-/** Check if a value lies in a (closed) range.
- *
- * @param x value to test
- * @param lo low end of the range
- * @param hi high end of the range
- * @return 1 if x is in the interval [lo, hi], 0 otherwise
- */
-inline static int in_range(int x, int lo, int hi){
-    return (lo <= x) && (x <= hi);
-}
-
-/** Determine if a string is an (unsigned) decimal number.
- * 
- * @param s pointer to characters to test
- * @param n length of string
- * @return 1 if s is a decimal number, 0 otherwise.
- */
-int is_decimal_number(const char *s, int n){
-    int i;
-    if(n <= 0)return 0;
-    for(i = 0; i < n; i++){
-        if(!in_decimal_digit_class(s[i])) return 0;
-    }
-    return 1;
-}
-
-/** Determine if a string is a hex number.
- * Hex numbers are 0, or start with 0x or 0X followed
- * by a non-zero number of hex digits (0-9,a-f,A-F).
- * 
- * @param s pointer to characters to test
- * @param n length of string
- * @return 1 if s is a hex number, 0 otherwise.
- */
-int is_hex_number(const char *s, int n){
-    int i;
-    if(n <= 0) return 0;
-    if(n == 1){
-        return s[0]=='0';
-    }
-    if(n <= 3) return 0;
-    if(s[0] != '0' || (s[1] != 'x' && s[1] != 'X')) return 0;
-    for(i = 2; i < n; i++){
-        if(!in_hex_digit_class(s[i])) return 0;
-    }
-    return 1;
-}
-
-/** Test if a string matches a keyword.
- * The comparison is case-insensitive.
- * The comparison fails if either argument is null.
- *
- * @param s string
- * @param k keyword
- * @return 1 if they match, 0 otherwise
- */
-int is_keyword(const char *s, const char *k){
-  return s && k && !strcasecmp(s, k);
-}
-
-/** Test if a string matches a character.
- *
- * @param s string
- * @param c character (non-null)
- * @return 1 if s contains exactly c, 0 otherwise
- */
-int is_keychar(const char *s, char c){
-  return c && (s[0] == c) && !s[1];
-}
diff --git a/tools/libxutil/lexis.h b/tools/libxutil/lexis.h
deleted file mode 100644 (file)
index d49a354..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#ifndef _XUTIL_LEXIS_H_
-#define _XUTIL_LEXIS_H_
-
-#include "sys_string.h"
-
-#ifdef __KERNEL__
-#  include <linux/ctype.h>
-#else
-#  include <ctype.h>
-#endif
-
-/** @file
- * Lexical analysis.
- */
-
-/** Class of characters treated as space. */
-#define space_class ((char []){ '\n', '\r', '\t', ' ', '\f' , 0 })
-
-/** Class of separator characters. */
-#define sep_class "{}()<>[]!;\"'"
-
-#define comment_class "#"
-
-/** Determine if a character is in a given class.
- * 
- * @param c character to test
- * @param s null-terminated string of characters in the class
- * @return 1 if c is in the class, 0 otherwise.
- */
-static inline int in_class(int c, const char *s){
-  return s && (strchr(s, c) != 0);
-}
-
-/** Determine if a character is in the space class.
- * 
- * @param c character to test
- * @return 1 if c is in the class, 0 otherwise.
- */
-static inline int in_space_class(int c){
-    return in_class(c, space_class);
-}
-
-static inline int in_comment_class(int c){
-    return in_class(c, comment_class);
-}
-
-/** Determine if a character is in the separator class.
- * Separator characters terminate tokens, and do not need space
- * to separate them.
- * 
- * @param c character to test
- * @return 1 if c is in the class, 0 otherwise.
- */
-static inline int in_sep_class(int c){
-    return in_class(c, sep_class);
-}
-
-/** Determine if a character is in the alpha class.
- * 
- * @param c character to test
- * @return 1 if c is in the class, 0 otherwise.
- */
-static inline int in_alpha_class(int c){
-    return isalpha(c);
-}
-
-/** Determine if a character is in the octal digit class.
- * 
- * @param c character to test
- * @return 1 if c is in the class, 0 otherwise.
- */
-static inline int in_octal_digit_class(int c){
-    return '0' <= c && c <= '7';
-}
-
-/** Determine if a character is in the decimal digit class.
- * 
- * @param c character to test
- * @return 1 if c is in the class, 0 otherwise.
- */
-static inline int in_decimal_digit_class(int c){
-    return isdigit(c);
-}
-
-/** Determine if a character is in the hex digit class.
- * 
- * @param c character to test
- * @return 1 if c is in the class, 0 otherwise.
- */
-static inline int in_hex_digit_class(int c){
-    return isdigit(c) || in_class(c, "abcdefABCDEF");
-}
-
-
-static inline int in_string_quote_class(int c){
-    return in_class(c, "'\"");
-}
-
-static inline int in_printable_class(int c){
-    return ('A' <= c && c <= 'Z')
-        || ('a' <= c && c <= 'z')
-        || ('0' <= c && c <= '9')
-        || in_class(c, "!$%&*+,-./:;<=>?@^_`{|}~");
-}
-
-extern int is_decimal_number(const char *s, int n);
-extern int is_hex_number(const char *s, int n);
-extern int is_keyword(const char *s, const char *k);
-extern int is_keychar(const char *s, char c);
-
-#endif /* !_XUTIL_LEXIS_H_ */
diff --git a/tools/libxutil/socket_stream.c b/tools/libxutil/socket_stream.c
deleted file mode 100644 (file)
index 9e90b4e..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/** @file
- * An IOStream implementation using sockets.
- */
-#ifndef __KERNEL__
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include "allocate.h"
-#include "socket_stream.h"
-
-#define MODULE_NAME "sock"
-#define DEBUG 0
-//#undef DEBUG
-#include "debug.h"
-
-static int socket_read(IOStream *s, void *buf, size_t n);
-static int socket_write(IOStream *s, const void *buf, size_t n);
-static int socket_error(IOStream *s);
-static int socket_close(IOStream *s);
-static void socket_free(IOStream *s);
-static int socket_flush(IOStream *s);
-
-/** Methods used by a socket IOStream. */
-static const IOMethods socket_methods = {
-    read:  socket_read,
-    write: socket_write,
-    error: socket_error,
-    close: socket_close,
-    free:  socket_free,
-    flush: socket_flush,
-};
-
-/** Get the socket data.
- * 
- * @param io socket stream
- * @return data
- */
-static inline SocketData * socket_data(IOStream *io){
-    return (SocketData *)io->data;
-}
-
-/** Test if a stream is a socket stream.
- *
- * @param io stream
- * @return 0 if a socket stream, -EINVAL if not
- */
-int socket_stream_check(IOStream *io){
-    return (io && io->methods == &socket_methods ? 0 : -EINVAL);
-}
-
-/** Get the data for a socket stream.
- *
- * @param io stream
- * @param data return value for the data
- * @return 0 if a socket stream, -EINVAL if not
- */
-int socket_stream_data(IOStream *io, SocketData **data){
-    int err = socket_stream_check(io);
-    if(err){
-        *data = NULL;
-    } else {
-        *data = socket_data(io);
-    }
-    return err;
-}
-
-/** Set the destination address for a socket stream.
- *
- * @param io stream
- * @param addr address
- * @return 0 if a socket stream, -EINVAL if not
- */
-int socket_stream_set_addr(IOStream *io, struct sockaddr_in *addr){
-    int err = 0;
-    SocketData *data = NULL;
-    err = socket_stream_data(io, &data);
-    if(!err){
-        data->daddr = *addr;
-    }
-    return err;
-}
-
-/** Set the send flags for a socket stream.
- *
- * @param io stream
- * @param flags flags
- * @return 0 if a socket stream, -EINVAL if not
- */
-int socket_stream_set_flags(IOStream *io, int flags){
-    int err = 0;
-    SocketData *data = NULL;
-    err = socket_stream_data(io, &data);
-    if(!err){
-        data->flags = flags;
-    }
-    return err;
-}
-
-/** Write to the underlying socket using sendto.
- *
- * @param stream input
- * @param buf where to put input
- * @param n number of bytes to write
- * @return number of bytes written
- */
-static int socket_write(IOStream *s, const void *buf, size_t n){
-    SocketData *data = socket_data(s);
-    struct sockaddr *daddr = (struct sockaddr *)&data->daddr;
-    socklen_t daddr_n = sizeof(data->daddr);
-    int k;
-    dprintf("> sock=%d addr=%s:%d n=%d\n",
-            data->fd, inet_ntoa(data->daddr.sin_addr), ntohs(data->daddr.sin_port), n);
-    if(0){
-        struct sockaddr_in self = {};
-        socklen_t self_n;
-        getsockname(data->fd, (struct sockaddr *)&self, &self_n);
-        dprintf("> sockname sock=%d %s:%d\n",
-                data->fd, inet_ntoa(self.sin_addr), ntohs(self.sin_port));
-    }
-    k = sendto(data->fd, buf, n, data->flags, daddr, daddr_n);
-    dprintf("> sendto=%d\n", k);
-    return k;
-}
-
-/** Read from the underlying stream using recv();
- *
- * @param stream input
- * @param buf where to put input
- * @param n number of bytes to read
- * @return number of bytes read
- */
-static int socket_read(IOStream *s, void *buf, size_t n){
-    SocketData *data = socket_data(s);
-    int k;
-    struct sockaddr *saddr = (struct sockaddr *)&data->saddr;
-    socklen_t saddr_n = sizeof(data->saddr);
-    k = recvfrom(data->fd, buf, n, data->flags, saddr, &saddr_n);
-    return k;
-}
-
-/** Flush the socket (no-op).
- *
- * @param s socket stream
- * @return 0 on success, error code otherwise
- */
-static int socket_flush(IOStream *s){
-    return 0;
-}
-
-/** Check if a socket stream has an error (no-op).
- *
- * @param s socket stream
- * @return 1 if has an error, 0 otherwise
- */
-static int socket_error(IOStream *s){
-    // Read SOL_SOCKET/SO_ERROR ?
-    return 0;
-}
-
-/** Close a socket stream.
- *
- * @param s socket stream to close
- * @return result of the close
- */
-static int socket_close(IOStream *s){
-    SocketData *data = socket_data(s);
-    return close(data->fd);
-}
-
-/** Free a socket stream.
- *
- * @param s socket stream
- */
-static void socket_free(IOStream *s){
-    SocketData *data = socket_data(s);
-    deallocate(data);
-}
-
-/** Create an IOStream for a socket.
- *
- * @param fd socket to wtap
- * @return new IOStream using fd for i/o
- */
-IOStream *socket_stream_new(int fd){
-    int err = -ENOMEM;
-    IOStream *io = NULL;
-    SocketData *data = NULL;
-
-    io = ALLOCATE(IOStream);
-    if(!io) goto exit;
-    io->methods = &socket_methods;
-    data = ALLOCATE(SocketData);
-    if(!data) goto exit;
-    io->data = data;
-    data->fd = fd;
-    data->buf_n = sizeof(data->buf);
-    err = 0;
-  exit:
-    if(err){
-        if(io){
-            if(data) deallocate(data);
-            deallocate(io);
-            io = NULL;
-        }
-    }
-    return io;
-}
-
-#endif
diff --git a/tools/libxutil/socket_stream.h b/tools/libxutil/socket_stream.h
deleted file mode 100644 (file)
index 9da23e9..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XEN_LIB_SOCKET_STREAM_H_
-#define _XEN_LIB_SOCKET_STREAM_H_
-
-#ifndef __KERNEL__
-#include "iostream.h"
-#include <stdio.h>
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-/** Data associated with a socket stream. */
-typedef struct SocketData {
-    /** The socket file descriptor. */
-    int fd;
-    /** Source address from last read (recvfrom). */
-    struct sockaddr_in saddr;
-    /** Destination address for writes (sendto). */
-    struct sockaddr_in daddr;
-    /** Write flags (sendto). */
-    int flags;
-    /** Buffer size. */
-    int buf_n;
-    /** Buffer for formatted printing. */
-    char buf[1024];
-} SocketData;
-
-extern IOStream *socket_stream_new(int fd);
-extern int socket_stream_data(IOStream *io, SocketData **data);
-extern int socket_stream_check(IOStream *io);
-extern int socket_stream_set_addr(IOStream *io, struct sockaddr_in *addr);
-extern int socket_stream_set_flags(IOStream *io, int flags);
-
-#endif
-#endif /* !_XEN_LIB_SOCKET_STREAM_H_ */
diff --git a/tools/libxutil/string_stream.c b/tools/libxutil/string_stream.c
deleted file mode 100644 (file)
index 907e7d7..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/** @file
- * IOStream subtype for input and output to strings.
- * Usable from user or kernel code (with __KERNEL__ defined).
- */
-
-#include "sys_string.h"
-#include "string_stream.h"
-#include "allocate.h"
-
-static int string_error(IOStream *io);
-static int string_close(IOStream *io);
-static void string_free(IOStream *io);
-static int string_write(IOStream *io, const void *msg, size_t n);
-static int string_read(IOStream *io, void *buf, size_t n);
-
-/** Methods for a string stream. */
-static IOMethods string_methods = {
-    read:  string_read,
-    write: string_write,
-    error: string_error,
-    close: string_close,
-    free:  string_free,
-};
-
-/** Get the string stream state.
- *
- * @param io string stream
- * @return state
- */
-static inline StringData *get_string_data(IOStream *io){
-    return (StringData*)io->data;
-}
-
-static int string_write(IOStream *io, const void *msg, size_t n){
-    StringData *data = get_string_data(io);
-    int k;
-
-    k = data->end - data->out;
-    if(n > k) n = k;
-    memcpy(data->out, msg, n);
-    data->out += n;
-    return n;
-}
-
-static int string_read(IOStream *io, void *buf, size_t n){
-    StringData *data = get_string_data(io);
-    int k;
-
-    k = data->end - data->in;
-    if(n > k) n = k;
-    memcpy(buf, data->in, k);
-    data->in += n;
-    return n;
-}
-
-/** Test if a string stream has an error.
- *
- * @param io string stream
- * @return 0 if ok, error code otherwise
- */
-static int string_error(IOStream *io){
-    StringData *data = get_string_data(io);
-    return data->out == NULL;
-}
-
-/** Close a string stream.
- *
- * @param io string stream
- * @return 0
- */
-static int string_close(IOStream *io){
-    StringData *data = get_string_data(io);
-    data->in = NULL;
-    data->out = NULL;
-    return 0;
-}
-
-/** Free a string stream.
- * The stream state is freed, but the underlying string is not.
- *
- * @param io string stream
- */
-static void string_free(IOStream *io){
-    StringData *data = get_string_data(io);
-    memzero(data, sizeof(*data));
-    deallocate(data);
-}
-
-/** Get the methods to use for a string stream.
- *
- * @return methods
- */
-IOMethods *string_stream_get_methods(void){
-    return &string_methods;
-}
-
-/** Initialise a string stream, usually from static data.
- * If the stream and StringData should be freed when
- * the stream is closed, unset io->nofree.
- * The string is not freed on close.
- *
- * @param io address of IOStream to fill in
- * @param data address of StringData to fill in
- * @param s string to use
- * @param n length of the string
- */
-void string_stream_init(IOStream *io, StringData *data, char *s, int n){
-    if(data && io){
-        memzero(data, sizeof(*data));
-        data->string = (char*)s;
-        data->in = data->string;
-        data->out = data->string;
-        data->size = n;
-        data->end = data->string + n;
-        memzero(io, sizeof(*io));
-        io->methods = &string_methods;
-        io->data = data;
-        io->nofree = 1;
-    }
-}
-
-/** Allocate and initialise a string stream.
- * The stream is freed on close, but the string is not.
- *
- * @param s string to use
- * @param n length of the string
- * @return new stream (free using IOStream_free)
- */
-IOStream *string_stream_new(char *s, int n){
-    int ok = 0;
-    StringData *data = ALLOCATE(StringData);
-    IOStream *io = ALLOCATE(IOStream);
-    if(data && io){
-        ok = 1;
-        string_stream_init(io, data, s, n);
-        io->nofree = 0;
-    }
-    if(!ok){
-        deallocate(data);
-        deallocate(io);
-        io = NULL;
-    }
-    return io;
-}
diff --git a/tools/libxutil/string_stream.h b/tools/libxutil/string_stream.h
deleted file mode 100644 (file)
index 246e63d..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XUTIL_STRING_STREAM_H_
-#define _XUTIL_STRING_STREAM_H_
-
-#include "iostream.h"
-
-/** Internal state for a string stream.
- * Exposed here so that string streams can be statically created, using
- * string_stream_init().
- */
-typedef struct {
-    /** The string used for input and ouput. */
-    char *string;
-    /** Output pointer. */
-    char *out;
-    /** Input pointer. */
-    char *in;
-    /** Length of string. */
-    int size;
-    /** End marker. */
-    char *end;
-} StringData;
-
-extern IOMethods *string_stream_get_methods(void);
-extern IOStream *string_stream_new(char *s, int n);
-extern void string_stream_init(IOStream *stream, StringData *data, char *s, int n);
-
-#endif /* !_XUTIL_STRING_STREAM_H_ */
diff --git a/tools/libxutil/sxpr.c b/tools/libxutil/sxpr.c
deleted file mode 100644 (file)
index d264527..0000000
+++ /dev/null
@@ -1,1230 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#include <stdarg.h>
-#include "sys_string.h"
-#include "lexis.h"
-#include "sys_net.h"
-#include "hash_table.h"
-#include "sxpr.h"
-
-#ifdef __KERNEL__
-#include <linux/errno.h>
-#else
-#include <errno.h>
-#endif
-
-#ifdef __KERNEL__
-#include <linux/random.h>
-
-int rand(void){
-    int v;
-    get_random_bytes(&v, sizeof(v));
-    return v;
-}
-
-#else
-#include <stdlib.h>
-#endif
-
-#undef free
-
-/** @file
- * General representation of sxprs.
- * Includes print, equal, and free functions for the sxpr types.
- *
- * Zero memory containing an Sxpr will have the value ONONE - this is intentional.
- * When a function returning an sxpr cannot allocate memory we return ONOMEM.
- *
- */
-
-static int atom_print(IOStream *io, Sxpr obj, unsigned flags);
-static int atom_equal(Sxpr x, Sxpr y);
-static void atom_free(Sxpr obj);
-static Sxpr atom_copy(Sxpr obj);
-
-static int string_print(IOStream *io, Sxpr obj, unsigned flags);
-static int string_equal(Sxpr x, Sxpr y);
-static void string_free(Sxpr obj);
-static Sxpr string_copy(Sxpr obj);
-
-static int cons_print(IOStream *io, Sxpr obj, unsigned flags);
-static int cons_equal(Sxpr x, Sxpr y);
-static void cons_free(Sxpr obj);
-static Sxpr cons_copy(Sxpr obj);
-
-static int null_print(IOStream *io, Sxpr obj, unsigned flags);
-static int none_print(IOStream *io, Sxpr obj, unsigned flags);
-static int int_print(IOStream *io, Sxpr obj, unsigned flags);
-static int bool_print(IOStream *io, Sxpr obj, unsigned flags);
-static int err_print(IOStream *io, Sxpr obj, unsigned flags);
-static int nomem_print(IOStream *io, Sxpr obj, unsigned flags);
-
-/** Type definitions. */
-static SxprType types[1024] = {
-    [T_NONE]     { .type=    T_NONE,     .name= "none",       .print= none_print      },
-    [T_NULL]     { .type=    T_NULL,     .name= "null",       .print= null_print      },
-    [T_UINT]     { .type=    T_UINT,     .name= "int",        .print= int_print,      },
-    [T_BOOL]     { .type=    T_BOOL,     .name= "bool",       .print= bool_print,     },
-    [T_ERR]      { .type=    T_ERR,      .name= "err",        .print= err_print,      },
-    [T_NOMEM]    { .type=    T_ERR,      .name= "nomem",      .print= nomem_print,    },
-    [T_ATOM]     { .type=    T_ATOM,     .name= "atom",       .print= atom_print,
-                   .pointer= TRUE,
-                   .free=    atom_free,
-                   .equal=   atom_equal,
-                   .copy=    atom_copy,
-                 },
-    [T_STRING]   { .type=    T_STRING,   .name= "string",     .print= string_print,
-                   .pointer= TRUE,
-                   .free=    string_free,
-                   .equal=   string_equal,
-                   .copy=    string_copy,
-                 },
-    [T_CONS]     { .type=    T_CONS,     .name= "cons",       .print= cons_print,
-                   .pointer= TRUE,
-                   .free=    cons_free,
-                   .equal=   cons_equal,
-                   .copy=    cons_copy,
-                 },
-};
-
-/** Number of entries in the types array. */
-static int type_sup = sizeof(types)/sizeof(types[0]);
-
-/** Define a type.
- * The tydef must have a non-zero type code.
- * It is an error if the type code is out of range or already defined.
- *
- * @param tydef type definition
- * @return 0 on success, error code otherwise
- */
-int def_sxpr_type(SxprType *tydef){
-    int err = 0;
-    int ty = tydef->type;
-    if(ty < 0 || ty >= type_sup){
-        err = -EINVAL;
-        goto exit;
-    }
-    if(types[ty].type){
-        err = -EEXIST;
-        goto exit;
-    }
-    types[ty] = *tydef;
-  exit:
-    return err;
-    
-}
-
-/** Get the type definition for a given type code.
- *
- * @param ty type code
- * @return type definition or null
- */
-SxprType *get_sxpr_type(int ty){
-    if(0 <= ty && ty < type_sup){
-        return types+ty;
-    }
-    return NULL;
-}
-
-/** The default print function.
- *
- * @param io stream to print to
- * @param x sxpr to print
- * @param flags print flags
- * @return number of bytes written on success
- */
-int default_print(IOStream *io, Sxpr x, unsigned flags){
-    return IOStream_print(io, "#<%u %lu>\n", get_type(x), get_ul(x));
-}
-
-/** The default equal function.
- * Uses eq().
- *
- * @param x sxpr to compare
- * @param y sxpr to compare
- * @return 1 if equal, 0 otherwise
- */
-int default_equal(Sxpr x, Sxpr y){
-    return eq(x, y);
-}
-
-/** General sxpr print function.
- * Prints an sxpr on a stream using the print function for the sxpr type.
- * Printing is controlled by flags from the PrintFlags enum.
- * If PRINT_TYPE is in the flags the sxpr type is printed before the sxpr
- * (for debugging).
- *
- * @param io stream to print to
- * @param x sxpr to print
- * @param flags print flags
- * @return number of bytes written
- */
-int objprint(IOStream *io, Sxpr x, unsigned flags){
-    SxprType *def = get_sxpr_type(get_type(x));
-    ObjPrintFn *print_fn = (def && def->print ? def->print : default_print);
-    int k = 0;
-    if(!io) return k;
-    if(flags & PRINT_TYPE){
-        k += IOStream_print(io, "%s:", def->name);
-    }
-    if(def->pointer && (flags & PRINT_ADDR)){
-        k += IOStream_print(io, "<%p>", get_ptr(x));
-    }
-    k += print_fn(io, x, flags);
-    return k;
-}
-
-Sxpr objcopy(Sxpr x){
-    SxprType *def = get_sxpr_type(get_type(x));
-    ObjCopyFn *copy_fn = (def ? def->copy : NULL);
-    Sxpr v;
-    if(copy_fn){
-        v = copy_fn(x);
-    } else if(def->pointer){
-        v = ONOMEM;
-    } else {
-        v = x;
-    }
-    return v;
-}
-
-/** General sxpr free function.
- * Frees an sxpr using the free function for its type.
- * Free functions must recursively free any subsxprs.
- * If no function is defined then the default is to
- * free sxprs whose type has pointer true.
- * Sxprs must not be used after freeing.
- *
- * @param x sxpr to free
- */
-void objfree(Sxpr x){
-    SxprType *def = get_sxpr_type(get_type(x));
-
-    if(def){
-        if(def->free){
-            def->free(x);
-        } else if (def->pointer){
-            hfree(x);
-        }
-    }
-}
-
-/** General sxpr equality function.
- * Compares x and y using the equal function for x.
- * Uses default_equal() if x has no equal function.
- *
- * @param x sxpr to compare
- * @param y sxpr to compare
- * @return 1 if equal, 0 otherwise
- */
-int objequal(Sxpr x, Sxpr y){
-    SxprType *def = get_sxpr_type(get_type(x));
-    ObjEqualFn *equal_fn = (def && def->equal ? def->equal : default_equal);
-    return equal_fn(x, y);
-}
-
-/** Search for a key in an alist.
- * An alist is a list of conses, where the cars
- * of the conses are the keys. Compares keys using equality.
- *
- * @param k key
- * @param l alist to search
- * @return first element of l with car k, or ONULL
- */
-Sxpr assoc(Sxpr k, Sxpr l){
-    for( ; CONSP(l) ; l = CDR(l)){
-        Sxpr x = CAR(l);
-        if(CONSP(x) && objequal(k, CAR(x))){
-            return x;   
-        }
-    }
-    return ONULL;
-}
-
-/** Search for a key in an alist.
- * An alist is a list of conses, where the cars
- * of the conses are the keys. Compares keys using eq.
- *
- * @param k key
- * @param l alist to search
- * @return first element of l with car k, or ONULL
- */
-Sxpr assocq(Sxpr k, Sxpr l){
-    for( ; CONSP(l); l = CDR(l)){
-        Sxpr x = CAR(l);
-        if(CONSP(x) && eq(k, CAR(x))){
-            return x;
-        }
-    }
-    return ONULL;
-}
-
-/** Add a new key and value to an alist.
- *
- * @param k key
- * @param l value
- * @param l alist
- * @return l with the new cell added to the front
- */
-Sxpr acons(Sxpr k, Sxpr v, Sxpr l){
-    Sxpr x, y;
-    x = cons_new(k, v);
-    if(NOMEMP(x)) return x;
-    y = cons_new(x, l);
-    if(NOMEMP(y)) cons_free_cells(x);
-    return y;
-}
-
-/** Test if a list contains an element.
- * Uses sxpr equality.
- *
- * @param l list
- * @param x element to look for
- * @return a tail of l with x as car, or ONULL
- */
-Sxpr cons_member(Sxpr l, Sxpr x){
-    for( ; CONSP(l) && !eq(x, CAR(l)); l = CDR(l)){}
-    return l;
-}
-
-/** Test if a list contains an element satisfying a test.
- * The test function is called with v and an element of the list.
- *
- * @param l list
- * @param test_fn test function to use
- * @param v value for first argument to the test
- * @return a tail of l with car satisfying the test, or 0
- */
-Sxpr cons_member_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v){
-    for( ; CONSP(l) && !test_fn(v, CAR(l)); l = CDR(l)){ }
-    return l;
-}
-
-/** Test if the elements of list 't' are a subset of the elements
- * of list 's'. Element order is not significant.
- *
- * @param s element list to check subset of
- * @param t element list to check if is a subset
- * @return 1 if is a subset, 0 otherwise
- */
-int cons_subset(Sxpr s, Sxpr t){
-    for( ; CONSP(t); t = CDR(t)){
-        if(!CONSP(cons_member(s, CAR(t)))){
-            return 0;
-        }
-    }
-    return 1;
-}
-
-/** Test if two lists have equal sets of elements.
- * Element order is not significant.
- *
- * @param s list to check
- * @param t list to check
- * @return 1 if equal, 0 otherwise
- */
-int cons_set_equal(Sxpr s, Sxpr t){
-    return cons_subset(s, t) && cons_subset(t, s);
-}
-
-#ifdef USE_GC
-/*============================================================================*/
-/* The functions inside this ifdef are only safe if GC is used.
- * Otherwise they may leak memory.
- */
-
-/** Remove an element from a list (GC only).
- * Uses sxpr equality and removes all instances, even
- * if there are more than one.
- *
- * @param l list to remove elements from
- * @param x element to remove
- * @return modified input list
- */
-Sxpr cons_remove(Sxpr l, Sxpr x){
-    return cons_remove_if(l, eq, x);
-}
-
-/** Remove elements satisfying a test (GC only).
- * The test function is called with v and an element of the set.
- *
- * @param l list to remove elements from
- * @param test_fn function to use to decide if an element should be removed
- * @return modified input list
- */
-Sxpr cons_remove_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v){
-    Sxpr prev = ONULL, elt, next;
-
-    for(elt = l; CONSP(elt); elt = next){
-        next = CDR(elt);
-        if(test_fn(v, CAR(elt))){
-            if(NULLP(prev)){
-                l = next;
-            } else {
-                CDR(prev) = next;
-            }
-        }
-    }
-    return l;
-}
-
-/** Set the value for a key in an alist (GC only).
- * If the key is present, changes the value, otherwise
- * adds a new cell.
- *
- * @param k key
- * @param v value
- * @param l alist
- * @return modified or extended list
- */
-Sxpr setf(Sxpr k, Sxpr v, Sxpr l){
-    Sxpr e = assoc(k, l);
-    if(NULLP(e)){
-        l = acons(k, v, l);
-    } else {
-        CAR(CDR(e)) = v;
-    }
-    return l;
-}
-/*============================================================================*/
-#endif /* USE_GC */
-
-/** Create a new atom with the given name.
- * Makes an integer sxpr if the name can be parsed as an int.
- *
- * @param name the name
- * @return new atom
- */
-Sxpr atom_new(char *name){
-    Sxpr n, obj = ONOMEM;
-    long v;
-
-    if(convert_atol(name, &v) == 0){
-        obj = OINT(v);
-    } else {
-        n = string_new(name);
-        if(NOMEMP(n)) goto exit;
-        obj = HALLOC(ObjAtom, T_ATOM);
-        if(NOMEMP(obj)){
-            string_free(n);
-            goto exit;
-        }
-        OBJ_ATOM(obj)->name = n;
-    }
-  exit:
-    return obj;
-}
-
-/** Free an atom.
- *
- * @param obj to free
- */
-void atom_free(Sxpr obj){
-    // Interned atoms are shared, so do not free.
-    if(OBJ_ATOM(obj)->interned) return;
-    objfree(OBJ_ATOM(obj)->name);
-    hfree(obj);
-}
-
-/** Copy an atom.
- *
- * @param obj to copy
- */
-Sxpr atom_copy(Sxpr obj){
-    Sxpr v;
-    if(OBJ_ATOM(obj)->interned){
-        v = obj;
-    } else {
-        v = atom_new(atom_name(obj));
-    }
-    return v;
-}
-
-/** Print an atom. Prints the atom name.
- *
- * @param io stream to print to
- * @param obj to print
- * @param flags print flags
- * @return number of bytes printed
- */
-int atom_print(IOStream *io, Sxpr obj, unsigned flags){
-    return objprint(io, OBJ_ATOM(obj)->name, flags);
-}
-
-/** Atom equality.
- *
- * @param x to compare
- * @param y to compare
- * @return 1 if equal, 0 otherwise
- */
-int atom_equal(Sxpr x, Sxpr y){
-    int ok;
-    ok = eq(x, y);
-    if(ok) goto exit;
-    ok = ATOMP(y) && string_equal(OBJ_ATOM(x)->name, OBJ_ATOM(y)->name);
-    if(ok) goto exit;
-    ok = STRINGP(y) && string_equal(OBJ_ATOM(x)->name, y);
-  exit:
-    return ok;
-}
-
-/** Get the name of an atom.
- *
- * @param obj atom
- * @return name
- */
-char * atom_name(Sxpr obj){
-    return string_string(OBJ_ATOM(obj)->name);
-}
-
-int atom_length(Sxpr obj){
-    return string_length(OBJ_ATOM(obj)->name);
-}
-
-/** Get the C string from a string sxpr.
- *
- * @param obj string sxpr
- * @return string
- */
-char * string_string(Sxpr obj){
-    return OBJ_STRING(obj)->data;
-}
-
-/** Get the length of a string.
- *
- * @param obj string
- * @return length
- */
-int string_length(Sxpr obj){
-    return OBJ_STRING(obj)->len;
-}
-
-/** Create a new string. The input string is copied,
- * and must be null-terminated.
- *
- * @param s characters to put in the string
- * @return new sxpr
- */
-Sxpr string_new(char *s){
-    int n = (s ? strlen(s) : 0);
-    return string_new_n(s, n);
-}
-
-/** Create a new string. The input string is copied,
- * and need not be null-terminated.
- *
- * @param s characters to put in the string (may be null)
- * @param n string length
- * @return new sxpr
- */
-Sxpr string_new_n(char *s, int n){
-    Sxpr obj;
-    obj = halloc(sizeof(ObjString) + n + 1, T_STRING);
-    if(!NOMEMP(obj)){
-        char *str = OBJ_STRING(obj)->data;
-        OBJ_STRING(obj)->len = n;
-        if(s){
-            memcpy(str, s, n);
-            str[n] = '\0';
-        } else {
-            memset(str, 0, n + 1);
-        }
-    }
-    return obj;
-}
-
-/** Free a string.
- *
- * @param obj to free
- */
-void string_free(Sxpr obj){
-    hfree(obj);
-}
-
-/** Copy a string.
- *
- * @param obj to copy
- */
-Sxpr string_copy(Sxpr obj){
-    return string_new_n(string_string(obj), string_length(obj));
-}
-
-/** Determine if a string needs escapes when printed
- * using the given flags.
- *
- * @param str string to check
- * @param n string length
- * @param flags print flags
- * @return 1 if needs escapes, 0 otherwise
- */
-int needs_escapes(char *str, int n, unsigned flags){
-    char *c;
-    int i;
-    int val = 0;
-
-    if(str){
-        for(i=0, c=str; i<n; i++, c++){
-            if(in_alpha_class(*c)) continue;
-            if(in_decimal_digit_class(*c)) continue;
-            if(in_class(*c, "/._+:@~-")) continue;
-            val = 1;
-            break;
-        }
-    }
-    return val;
-}
-
-char randchar(void){
-    int r;
-    char c;
-    for( ; ; ){
-        r = rand();
-        c = (r >> 16) & 0xff;
-        if('a' <= c && c <= 'z') break;
-    }
-    return c;
-}
-
-int string_contains(char *s, int s_n, char *k, int k_n){
-    int i, n = s_n - k_n;
-    for(i=0; i < n; i++){
-        if(!memcmp(s+i, k, k_n)) return 1;
-    }
-    return 0;
-}
-
-int string_delim(char *s, int s_n, char *d, int d_n){
-    int i;
-    if(d_n < 4) return -1;
-    memset(d, 0, d_n+1);
-    for(i=0; i<3; i++){
-        d[i] = randchar();
-    }
-    for( ; i < d_n; i++){
-        if(!string_contains(s, s_n, d, i)){
-            return i;
-        }
-        d[i] = randchar();
-    }
-    return -1;
-}
-
-/** Print the bytes in a string as-is.
- *
- * @param io stream
- * @param str string
- * @param n length
- * @return bytes written or error code
- */
-int _string_print_raw(IOStream *io, char *str, int n){
-    int k = 0;
-    k = IOStream_write(io, str, n);
-    return k;
-}
-
-/** Print a string in counted data format.
- *
- * @param io stream
- * @param str string
- * @param n length
- * @return bytes written or error code
- */
-int _string_print_counted(IOStream *io, char *str, int n){
-    int k = 0;
-    k += IOStream_print(io, "%c%c%d%c",
-                        c_data_open, c_data_count, n, c_data_count);
-    k += IOStream_write(io, str, n);
-    return k;
-}
-  
-/** Print a string in quoted data format.
- *
- * @param io stream
- * @param str string
- * @param n length
- * @return bytes written or error code
- */
-int _string_print_quoted(IOStream *io, char *str, int n){
-    int k = 0;
-    char d[10];
-    int d_n;
-    d_n = string_delim(str, n, d, sizeof(d) - 1);
-    k += IOStream_print(io, "%c%c%s%c",
-                        c_data_open, c_data_quote, d, c_data_quote);
-    k += IOStream_write(io, str, n);
-    k += IOStream_print(io, "%c%s%c", c_data_quote, d, c_data_quote);
-    return k;
-}
-
-/** Print a string as a quoted string.
- *
- * @param io stream
- * @param str string
- * @param n length
- * @return bytes written or error code
- */
-int _string_print_string(IOStream *io, char *str, int n){
-    int k = 0;
-    
-    k += IOStream_print(io, "\"");
-    if(str){
-        char *s, *t;
-        for(s = str, t = str + n; s < t; s++){
-            if(*s < ' ' || *s >= 127 ){
-                switch(*s){
-                case '\a': k += IOStream_print(io, "\\a");  break;
-                case '\b': k += IOStream_print(io, "\\b");  break;
-                case '\f': k += IOStream_print(io, "\\f");  break;
-                case '\n': k += IOStream_print(io, "\\n");  break;
-                case '\r': k += IOStream_print(io, "\\r");  break;
-                case '\t': k += IOStream_print(io, "\\t");  break;
-                case '\v': k += IOStream_print(io, "\\v");  break;
-                default:
-                    // Octal escape;
-                    k += IOStream_print(io, "\\%o", *s);
-                    break;
-                }
-            } else if(*s == c_double_quote ||
-                      *s == c_single_quote ||
-                      *s == c_escape){
-                k += IOStream_print(io, "\\%c", *s);
-            } else {
-                k+= IOStream_print(io, "%c", *s);
-            }
-        }
-    }
-    k += IOStream_print(io, "\"");
-    return k;
-}
-
-/** Print a string to a stream, with escapes if necessary.
- *
- * @param io stream to print to
- * @param str string
- * @param n string length
- * @param flags print flags
- * @return number of bytes written
- */
-int _string_print(IOStream *io, char *str, int n, unsigned flags){
-    int k = 0;
-    if((flags & PRINT_COUNTED)){
-        k = _string_print_counted(io, str, n);
-    } else if((flags & PRINT_RAW) || !needs_escapes(str, n, flags)){
-        k = _string_print_raw(io, str, n);
-    } else if(n > 50){
-        k = _string_print_quoted(io, str, n);
-    } else {
-        k = _string_print_string(io, str, n);
-    }
-    return k;
-}
-
-/** Print a string to a stream, with escapes if necessary.
- *
- * @param io stream to print to
- * @param obj string
- * @param flags print flags
- * @return number of bytes written
- */
-int string_print(IOStream *io, Sxpr obj, unsigned flags){
-    return _string_print(io,
-                         OBJ_STRING(obj)->data,
-                         OBJ_STRING(obj)->len,
-                         flags);
-}
-
-int string_eq(char *s, int s_n, char *t, int t_n){
-    return (s_n == t_n) && (memcmp(s, t, s_n) == 0);
-}
-
-/** Compare an sxpr with a string for equality.
- *
- * @param x string to compare with
- * @param y sxpr to compare
- * @return 1 if equal, 0 otherwise
- */
-int string_equal(Sxpr x, Sxpr y){
-    int ok = 0;
-    ok = eq(x,y);
-    if(ok) goto exit;
-    ok = has_type(y, T_STRING) &&
-        string_eq(OBJ_STRING(x)->data, OBJ_STRING(x)->len,
-                  OBJ_STRING(y)->data, OBJ_STRING(y)->len);
-    if(ok) goto exit;
-    ok = has_type(y, T_ATOM) &&
-        string_eq(OBJ_STRING(x)->data, OBJ_STRING(x)->len,
-                  atom_name(y), atom_length(y));
-  exit:
-    return ok;
-}
-
-/** Create a new cons cell.
- * The cell is ONOMEM if either argument is.
- *
- * @param car sxpr for the car
- * @param cdr sxpr for the cdr
- * @return new cons
- */
-Sxpr cons_new(Sxpr car, Sxpr cdr){
-    Sxpr obj;
-    if(NOMEMP(car) || NOMEMP(cdr)){
-        obj = ONOMEM;
-    } else {
-        obj = HALLOC(ObjCons, T_CONS);
-        if(!NOMEMP(obj)){
-            ObjCons *z = OBJ_CONS(obj);
-            z->car = car;
-            z->cdr = cdr;
-        }
-    }
-    return obj;
-}
-
-/** Push a new element onto a list.
- *
- * @param list list to add to
- * @param elt element to add
- * @return 0 if successful, error code otherwise
- */
-int cons_push(Sxpr *list, Sxpr elt){
-    Sxpr l;
-    l = cons_new(elt, *list);
-    if(NOMEMP(l)) return -ENOMEM;
-    *list = l;
-    return 0;
-}
-
-/** Free a cons. Recursively frees the car and cdr.
- *
- * @param obj to free
- */
-void cons_free(Sxpr obj){
-    Sxpr next;
-    for(; CONSP(obj); obj = next){
-        next = CDR(obj);
-        objfree(CAR(obj));
-        hfree(obj);
-    }
-    if(!NULLP(obj)){
-        objfree(obj);
-    }
-}
-
-/** Copy a cons. Recursively copies the car and cdr.
- *
- * @param obj to copy
- */
-Sxpr cons_copy(Sxpr obj){
-    Sxpr v = ONULL;
-    Sxpr l = ONULL, x = ONONE;
-    for(l = obj; CONSP(l); l = CDR(l)){
-        x = objcopy(CAR(l));
-        if(NOMEMP(x)) goto exit;
-        x = cons_new(x, v);
-        if(NOMEMP(x)) goto exit;
-        v = x;
-    }
-    v = nrev(v);
-  exit:
-    if(NOMEMP(x)){
-        objfree(v);
-        v = ONOMEM;
-    }
-    return v;
-}
-
-/** Free a cons and its cdr cells, but not the car sxprs.
- * Does nothing if called on something that is not a cons.
- *
- * @param obj to free
- */
-void cons_free_cells(Sxpr obj){
-    Sxpr next;
-    for(; CONSP(obj); obj = next){
-        next = CDR(obj);
-        hfree(obj);
-    }
-}
-
-/** Print a cons.
- * Prints the cons in list format if the cdrs are conses.
- * uses pair (dot) format if the last cdr is not a cons (or null).
- *
- * @param io stream to print to
- * @param obj to print
- * @param flags print flags
- * @return number of bytes written
- */
-int cons_print(IOStream *io, Sxpr obj, unsigned flags){
-    int first = 1;
-    int k = 0;
-    k += IOStream_print(io, "(");
-    for( ; CONSP(obj) ; obj = CDR(obj)){
-        if(first){ 
-            first = 0;
-        } else {
-            k += IOStream_print(io, " ");
-        }
-        k += objprint(io, CAR(obj), flags);
-    }
-    if(!NULLP(obj)){
-        k += IOStream_print(io, " . ");
-        k += objprint(io, obj, flags);
-    }
-    k += IOStream_print(io, ")");
-    return (IOStream_error(io) ? -1 : k);
-}
-
-/** Compare a cons with another sxpr for equality.
- * If y is a cons, compares the cars and cdrs recursively.
- *
- * @param x cons to compare
- * @param y sxpr to compare
- * @return 1 if equal, 0 otherwise
- */
-int cons_equal(Sxpr x, Sxpr y){
-    return CONSP(y) &&
-        objequal(CAR(x), CAR(y)) &&
-        objequal(CDR(x), CDR(y));
-}
-
-/** Return the length of a cons list.
- *
- * @param obj list
- * @return length
- */
-int cons_length(Sxpr obj){
-    int count = 0;
-    for( ; CONSP(obj); obj = CDR(obj)){
-        count++;
-    }
-    return count;
-}
-
-/** Destructively reverse a cons list in-place.
- * If the argument is not a cons it is returned unchanged.
- * 
- * @param l to reverse
- * @return reversed list
- */
-Sxpr nrev(Sxpr l){
-    if(CONSP(l)){
-        // Iterate down the cells in the list making the cdr of
-        // each cell point to the previous cell. The last cell 
-        // is the head of the reversed list.
-        Sxpr prev = ONULL;
-        Sxpr cell = l;
-        Sxpr next;
-
-        while(1){
-            next = CDR(cell);
-            CDR(cell) = prev;
-            if(!CONSP(next)) break;
-            prev = cell;
-            cell = next;
-        }
-        l = cell;
-    }
-    return l;
-}
-
-/** Print the null sxpr.        
- *
- * @param io stream to print to
- * @param obj to print
- * @param flags print flags
- * @return number of bytes written
- */
-static int null_print(IOStream *io, Sxpr obj, unsigned flags){
-    return IOStream_print(io, "()");
-}
-
-/** Print the `unspecified' sxpr none.
- *
- * @param io stream to print to
- * @param obj to print
- * @param flags print flags
- * @return number of bytes written
- */
-static int none_print(IOStream *io, Sxpr obj, unsigned flags){
-    return IOStream_print(io, "<none>");
-}
-
-/** Print an integer.
- *
- * @param io stream to print to
- * @param obj to print
- * @param flags print flags
- * @return number of bytes written
- */
-static int int_print(IOStream *io, Sxpr obj, unsigned flags){
-    return IOStream_print(io, "%d", OBJ_INT(obj));
-}
-
-/** Print a boolean.
- *
- * @param io stream to print to
- * @param obj to print
- * @param flags print flags
- * @return number of bytes written
- */
-static int bool_print(IOStream *io, Sxpr obj, unsigned flags){
-    return IOStream_print(io, (OBJ_UINT(obj) ? k_true : k_false));
-}
-
-/** Print an error.
- *
- * @param io stream to print to
- * @param obj to print
- * @param flags print flags
- * @return number of bytes written
- */
-static int err_print(IOStream *io, Sxpr obj, unsigned flags){
-    int err = OBJ_INT(obj);
-    if(err < 0) err = -err;
-    return IOStream_print(io, "[error:%d:%s]", err, strerror(err));
-}
-
-/** Print the 'nomem' sxpr.
- *
- * @param io stream to print to
- * @param obj to print
- * @param flags print flags
- * @return number of bytes written
- */
-static int nomem_print(IOStream *io, Sxpr obj, unsigned flags){
-    return IOStream_print(io, "[ENOMEM]");
-}
-
-int sxprp(Sxpr obj, Sxpr name){
-    return CONSP(obj) && objequal(CAR(obj), name);
-}
-
-/** Get the name of an element.
- * 
- * @param obj element
- * @return name
- */
-Sxpr sxpr_name(Sxpr obj){
-    Sxpr val = ONONE;
-    if(CONSP(obj)){
-        val = CAR(obj);
-    } else if(STRINGP(obj) || ATOMP(obj)){
-        val = obj;
-    }
-    return val;
-}
-
-int sxpr_is(Sxpr obj, char *s){
-    if(ATOMP(obj)) return string_eq(atom_name(obj), atom_length(obj), s, strlen(s));
-    if(STRINGP(obj)) return string_eq(string_string(obj), string_length(obj), s, strlen(s));
-    return 0;
-}
-
-int sxpr_elementp(Sxpr obj, Sxpr name){
-    int ok = 0;
-    ok = CONSP(obj) && objequal(CAR(obj), name);
-    return ok;
-}
-
-/** Get the attributes of an sxpr.
- * 
- * @param obj sxpr
- * @return attributes
- */
-Sxpr sxpr_attributes(Sxpr obj){
-    Sxpr val = ONULL;
-    if(CONSP(obj)){
-        obj = CDR(obj);
-        if(CONSP(obj)){
-            obj = CAR(obj);
-            if(sxprp(obj, intern("@"))){
-                val = CDR(obj);
-            }
-        }
-    }
-    return val;
-}
-
-Sxpr sxpr_attribute(Sxpr obj, Sxpr key, Sxpr def){
-    Sxpr val = ONONE;
-    val = assoc(sxpr_attributes(obj), key);
-    if(CONSP(val) && CONSP(CDR(val))){
-        val = CADR(def);
-    } else {
-        val = def;
-    }
-    return val;
-}
-
-/** Get the children of an sxpr.
- * 
- * @param obj sxpr
- * @return children
- */
-Sxpr sxpr_children(Sxpr obj){
-    Sxpr val = ONULL;
-    if(CONSP(obj)){
-        val = CDR(obj);
-        if(CONSP(val) && sxprp(CAR(val), intern("@"))){
-            val = CDR(val);
-        }
-    }
-    return val;
-}
-
-Sxpr sxpr_child(Sxpr obj, Sxpr name, Sxpr def){
-    Sxpr val = ONONE;
-    Sxpr l;
-    for(l = sxpr_children(obj); CONSP(l); l = CDR(l)){
-        if(sxprp(CAR(l), name)){
-            val = CAR(l);
-            break;
-        }
-    }
-    if(NONEP(val)) val = def;
-    return val;
-}
-
-Sxpr sxpr_child0(Sxpr obj, Sxpr def){
-    Sxpr val = ONONE;
-    Sxpr l = sxpr_children(obj);
-    if(CONSP(l)){
-        val = CAR(l);
-    } else {
-        val = def;
-    }
-    return val;
-}
-
-Sxpr sxpr_childN(Sxpr obj, int n, Sxpr def){
-    Sxpr val = def;
-    Sxpr l;
-    int i;
-    for (i = 0, l = sxpr_children(obj); CONSP(l); i++, l = CDR(l)){
-        if(i == n){
-            val = CAR(l);
-            break;
-        }
-    }
-    return val;
-}
-    
-Sxpr sxpr_child_value(Sxpr obj, Sxpr name, Sxpr def){
-    Sxpr val = ONONE;
-    val = sxpr_child(obj, name, ONONE);
-    if(NONEP(val)){
-        val = def;
-    } else {
-        val = sxpr_child0(val, def);
-    }
-    return val;
-}
-
-/** Table of interned symbols. Indexed by symbol name. */
-static HashTable *symbols = NULL;
-
-/** Hash function for entries in the symbol table.
- *
- * @param key to hash
- * @return hashcode
- */
-static Hashcode sym_hash_fn(void *key){
-    return hash_string((char*)key);
-}
-
-/** Key equality function for the symbol table.
- *
- * @param x to compare
- * @param y to compare
- * @return 1 if equal, 0 otherwise
- */
-static int sym_equal_fn(void *x, void *y){
-    return !strcmp((char*)x, (char*)y);
-}
-
-/** Entry free function for the symbol table.
- *
- * @param table the entry is in
- * @param entry being freed
- */
-static void sym_free_fn(HashTable *table, HTEntry *entry){
-    if(entry){
-        objfree(((ObjAtom*)entry->value)->name);
-        HTEntry_free(entry);
-    }
-}
-        
-/** Initialize the symbol table.
- *
- * @return 0 on sucess, error code otherwise
- */
-static int init_symbols(void){
-    symbols = HashTable_new(100);
-    if(symbols){
-        symbols->key_hash_fn = sym_hash_fn;
-        symbols->key_equal_fn = sym_equal_fn;
-        symbols->entry_free_fn = sym_free_fn;
-        return 0;
-    }
-    return -1;
-}
-
-/** Cleanup the symbol table. Frees the table and all its symbols.
- */
-void cleanup_symbols(void){
-    HashTable_free(symbols);
-    symbols = NULL;
-}
-
-/** Get the interned symbol with the given name.
- * No new symbol is created.
- *
- * @return symbol or null
- */
-Sxpr get_symbol(char *sym){
-    HTEntry *entry;
-    if(!symbols){
-        if(init_symbols()) return ONOMEM;
-        return ONULL;
-    }
-    entry = HashTable_get_entry(symbols, sym);
-    if(entry){
-        return OBJP(T_ATOM, entry->value);
-    } else {
-        return ONULL;
-    }
-}
-
-/** Get the interned symbol with the given name.
- * Creates a new symbol if necessary.
- *
- * @return symbol
- */
-Sxpr intern(char *sym){
-    Sxpr symbol = get_symbol(sym);
-    if(NULLP(symbol)){
-        if(!symbols) return ONOMEM;
-        symbol = atom_new(sym);
-        if(!NOMEMP(symbol)){
-            OBJ_ATOM(symbol)->interned = TRUE;
-            HashTable_add(symbols, atom_name(symbol), get_ptr(symbol));
-        }
-    }
-    return symbol;
-}
diff --git a/tools/libxutil/sxpr.h b/tools/libxutil/sxpr.h
deleted file mode 100644 (file)
index c9acd7b..0000000
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-#ifndef _XUTIL_SXPR_H_
-#define _XUTIL_SXPR_H_
-
-#ifdef __KERNEL__
-#include <linux/config.h>
-#include <linux/types.h>
-#else
-#include <stdint.h>
-#endif
-
-#include "hash_table.h"
-#include "iostream.h"
-#include "allocate.h"
-
-/** @file
- * Definitions for rules and sxprs.
- */
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-/** Sxpr type. */
-typedef int16_t TypeCode;
-
-/** A typed sxpr handle.*/
-typedef struct Sxpr {
-    /** Sxpr type. */
-    TypeCode type;
-    union {
-        /** Sxpr value. */
-        unsigned long ul;
-        /** Pointer. */
-        void *ptr;
-    } v;
-} Sxpr;
-
-/** Get the integer value from an sxpr.
- *
- * @param obj sxpr
- * @return value
- */
-static inline unsigned long get_ul(Sxpr obj){
-    return obj.v.ul;
-}
-
-/** Get the pointer value from an sxpr.
- *
- * @param obj sxpr
- * @return value
- */
-static inline void * get_ptr(Sxpr obj){
-    return obj.v.ptr;
-}
-
-/** Create an sxpr containing a pointer.
- *
- * @param ty typecode
- * @param val pointer
- * @return sxpr
- */
-static inline Sxpr obj_ptr(TypeCode ty, void *val){
-    return (Sxpr){ .type= ty, .v= { .ptr= val } };
-}
-
-/** Create an sxpr containing an integer.
- *
- * @param ty typecode
- * @param val integer
- * @return sxpr
- */
-static inline Sxpr obj_ul(TypeCode ty, unsigned long val){
-    return (Sxpr){ .type= ty, .v= { .ul= val } };
-}
-
-/** Get the type of an sxpr.
- *
- * @param obj sxpr
- * @return type
- */
-static inline TypeCode get_type(Sxpr obj){
-    return obj.type;
-}
-
-/** Check the type of an sxpr.
- *
- * @param obj sxpr
- * @param type to check
- * @return 1 if has the type, 0 otherwise
- */
-static inline int has_type(Sxpr obj, TypeCode type){
-    return get_type(obj) == type;
-}
-
-/** Compare sxprs for literal equality of type and value.
- *
- * @param x sxpr to compare
- * @param y sxpr to compare
- * @return 1 if equal, 0 otherwise
- */
-static inline int eq(Sxpr x, Sxpr y){
-    return ((get_type(x) == get_type(y)) && (get_ul(x) == get_ul(y)));
-}
-
-/** The 'unspecified' sxpr. */
-#define T_NONE       ((TypeCode)0)
-/** The empty list. */
-#define T_NULL       ((TypeCode)1)
-/** Unsigned integer. */
-#define T_UINT       ((TypeCode)2)
-/** A string. */
-#define T_STRING     ((TypeCode)3)
-/** An atom. */
-#define T_ATOM       ((TypeCode)4)
-/** A boolean. */
-#define T_BOOL       ((TypeCode)5)
-
-/** A cons (pair or list). */
-#define T_CONS       ((TypeCode)10)
-
-/** An error. */
-#define T_ERR        ((TypeCode)40)
-/** Sxpr type to indicate out of memory. */
-#define T_NOMEM      ((TypeCode)41)
-
-typedef struct ObjString {
-    int len;
-    char data[];
-} ObjString;
-
-/** An atom. */
-typedef struct ObjAtom {
-    Sxpr name;
-    Hashcode hashcode;
-    int interned;
-} ObjAtom;
-
-/** A cons (pair). */
-typedef struct ObjCons {
-    Sxpr car;
-    Sxpr cdr;
-} ObjCons;
-
-/** Flags for sxpr printing. */
-enum PrintFlags {
-    PRINT_RAW           = 0x001,
-    PRINT_TYPE          = 0x002,
-    PRINT_PRETTY        = 0x004,
-    PRINT_COUNTED       = 0x008,
-    PRINT_ADDR          = 0x010,
-};
-
-extern int _string_print(IOStream *io, char *str, int n, unsigned flags);
-extern int _string_print_raw(IOStream *io, char *str, int n);
-extern int _string_print_counted(IOStream *io, char *str, int n);
-extern int _string_print_quoted(IOStream *io, char *str, int n);
-extern int _string_print_string(IOStream *io, char *str, int n);
-
-/** An integer sxpr.
- *
- * @param ty type
- * @param val integer value
- */
-#define OBJI(ty, val) obj_ul(ty, val)
-
-/** Make an integer sxpr.
- * @param x value
- */
-#define OINT(x)       OBJI(T_UINT,  x)
-
-/** Make an error sxpr.
- *
- * @param x value
- */
-#define OERR(x)       OBJI(T_ERR,   x)
-
-/** Out of memory constant. */
-#define ONOMEM        OBJI(T_NOMEM, 0)
-
-/** The `unspecified' constant. */
-#define ONONE         OBJI(T_NONE,  0)
-
-/** Empty list constant. */
-#define ONULL         OBJI(T_NULL,  0)
-
-/** False constant. */
-#define OFALSE        OBJI(T_BOOL,  0)
-
-/** True constant. */
-#define OTRUE         OBJI(T_BOOL,  1)
-
-/** A pointer sxpr.
- * If the pointer is non-null, returns an sxpr containing it.
- * If the pointer is null, returns ONOMEM.
- *
- * @param ty type
- * @param val pointer
- */
-static inline Sxpr OBJP(int ty, void *val){
-    return (val ? obj_ptr(ty, val) : ONOMEM);
-}
-
-/** Make an integer sxpr containing a pointer.
- *
- * @param val pointer
- */
-#define PTR(val) OBJP(T_UINT, (void*)(val))
-
-/** Allocate some memory and return an sxpr containing it.
- * Returns ONOMEM if allocation failed.
- *
- * @param n number of bytes to allocate
- * @param ty typecode
- * @return sxpr
- */
-#define halloc(_n, _ty) OBJP(_ty, allocate(_n))
-
-/** Allocate an sxpr containing a pointer to the given type.
- *
- * @param _ctype type (uses sizeof to determine how many bytes to allocate)
- * @param _tycode typecode
- * @return sxpr, ONOMEM if allocation failed
- */
-#define HALLOC(_ctype, _tycode) halloc(sizeof(_ctype), _tycode)
-
-/* Recognizers for the various sxpr types.  */
-#define ATOMP(obj)        has_type(obj, T_ATOM)
-#define BOOLP(obj)        has_type(obj, T_BOOL)
-#define CONSP(obj)        has_type(obj, T_CONS)
-#define ERRP(obj)         has_type(obj, T_ERR)
-#define INTP(obj)         has_type(obj, T_UINT)
-#define NOMEMP(obj)       has_type(obj, T_NOMEM)
-#define NONEP(obj)        has_type(obj, T_NONE)
-#define NULLP(obj)        has_type(obj, T_NULL)
-#define STRINGP(obj)      has_type(obj, T_STRING)
-
-#define TRUEP(obj)    get_ul(obj)
-
-/** Convert an sxpr to an unsigned integer. */
-#define OBJ_UINT(x)   get_ul(x)
-/** Convert an sxpr to an integer. */
-#define OBJ_INT(x)    (int)get_ul(x)
-
-/* Conversions of sxprs to their values.
- * No checking is done.
- */
-#define OBJ_STRING(x)  ((ObjString*)get_ptr(x))
-#define OBJ_CONS(x)    ((ObjCons*)get_ptr(x))
-#define OBJ_ATOM(x)    ((ObjAtom*)get_ptr(x))
-#define OBJ_SET(x)     ((ObjSet*)get_ptr(x))
-#define CAR(x)         (OBJ_CONS(x)->car)
-#define CDR(x)         (OBJ_CONS(x)->cdr)
-
-#define CAAR(x)        (CAR(CAR(x)))
-#define CADR(x)        (CAR(CDR(x)))
-#define CDAR(x)        (CDR(CAR(x)))
-#define CDDR(x)        (CDR(CDR(x)))
-
-/** Checked version of CAR
- *
- * @param x sxpr
- * @return CAR if a cons, x otherwise
- */
-static inline Sxpr car(Sxpr x){
-    return (CONSP(x) ? CAR(x) : x);
-}
-
-/** Checked version of CDR.
- *
- * @param x sxpr
- * @return CDR if a cons, null otherwise
- */
-static inline Sxpr cdr(Sxpr x){
-    return (CONSP(x) ? CDR(x) : ONULL);
-}
-
-typedef int ObjPrintFn(IOStream *io, Sxpr obj, unsigned flags);
-typedef int ObjEqualFn(Sxpr obj, Sxpr other);
-typedef void ObjFreeFn(Sxpr obj);
-typedef Sxpr ObjCopyFn(Sxpr obj);
-
-/** An sxpr type definition. */
-typedef struct SxprType {
-    TypeCode type;
-    char *name;
-    int pointer;
-    ObjPrintFn *print;
-    ObjEqualFn *equal;
-    ObjFreeFn *free;
-    ObjCopyFn *copy;
-} SxprType;
-
-
-extern int def_sxpr_type(SxprType *tydef);
-extern SxprType *get_sxpr_type(int ty);
-
-/** Free the pointer in an sxpr.
- *
- * @param x sxpr containing a pointer
- */
-static inline void hfree(Sxpr x){
-    deallocate(get_ptr(x));
-}
-
-extern int objprint(IOStream *io, Sxpr x, unsigned flags);
-extern int objequal(Sxpr x, Sxpr y);
-extern void objfree(Sxpr x);
-extern Sxpr objcopy(Sxpr x);
-
-extern void cons_free_cells(Sxpr obj);
-extern Sxpr intern(char *s);
-
-extern Sxpr assoc(Sxpr k, Sxpr l);
-extern Sxpr assocq(Sxpr k, Sxpr l);
-extern Sxpr acons(Sxpr k, Sxpr v, Sxpr l);
-extern Sxpr nrev(Sxpr l);
-extern Sxpr cons_member(Sxpr l, Sxpr x);
-extern Sxpr cons_member_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v);
-extern int cons_subset(Sxpr s, Sxpr t);
-extern int cons_set_equal(Sxpr s, Sxpr t);
-
-#ifdef USE_GC
-extern Sxpr cons_remove(Sxpr l, Sxpr x);
-extern Sxpr cons_remove_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v);
-#endif
-
-extern Sxpr atom_new(char *name);
-extern char * atom_name(Sxpr obj);
-extern int atom_length(Sxpr obj);
-
-extern Sxpr string_new(char *s);
-extern Sxpr string_new_n(char *s, int n);
-extern char * string_string(Sxpr obj);
-extern int string_length(Sxpr obj);
-
-extern Sxpr cons_new(Sxpr car, Sxpr cdr);
-extern int cons_push(Sxpr *list, Sxpr elt);
-extern int cons_length(Sxpr obj);
-
-Sxpr sxpr_name(Sxpr obj);
-int sxpr_is(Sxpr obj, char *s);
-int sxpr_elementp(Sxpr obj, Sxpr name);
-Sxpr sxpr_attributes(Sxpr obj);
-Sxpr sxpr_attribute(Sxpr obj, Sxpr key, Sxpr def);
-Sxpr sxpr_children(Sxpr obj);
-Sxpr sxpr_child(Sxpr obj, Sxpr name, Sxpr def);
-Sxpr sxpr_childN(Sxpr obj, int n, Sxpr def);
-Sxpr sxpr_child0(Sxpr obj, Sxpr def);
-Sxpr sxpr_child_value(Sxpr obj, Sxpr name, Sxpr def);
-
-/** Create a new atom.
- *
- * @param s atom name
- * @return new atom
- */
-static inline Sxpr mkatom(char *s){
-    return atom_new(s);
-}
-
-/** Create a new string sxpr.
- *
- * @param s string bytes (copied)
- * @return new string
- */
-static inline Sxpr mkstring(char *s){
-    return string_new(s);
-}
-
-/** Create an integer sxpr.
- *
- * @param i value
- * @return sxpr
- */
-static inline Sxpr mkint(int i){
-    return OBJI(T_UINT, i);
-}
-
-/** Create a boolean sxpr.
- *
- * @param b value
- * @return sxpr
- */
-static inline Sxpr mkbool(int b){
-    return OBJI(T_BOOL, (b ? 1 : 0));
-}
-
-/* Constants used in parsing and printing. */
-#define k_list_open    "("
-#define c_list_open    '('
-#define k_list_close   ")"
-#define c_list_close   ')'
-#define k_true         "true"
-#define k_false        "false"
-
-#define c_escape       '\\'
-#define c_single_quote '\''
-#define c_double_quote '"'
-#define c_string_open  c_double_quote
-#define c_string_close c_double_quote
-
-#define c_data_open    '<'
-#define c_data_quote   '<'
-#define c_data_count   '*'
-//#define c_data_open    '['
-//#define c_data_close   ']'
-//#define c_binary       '*'
-
-#define c_var          '$'
-#define c_eval         '!'
-#define c_concat_open  '{'
-#define c_concat_close '}'
-
-#endif /* ! _XUTIL_SXPR_H_ */
diff --git a/tools/libxutil/sxpr_parser.c b/tools/libxutil/sxpr_parser.c
deleted file mode 100644 (file)
index f93d350..0000000
+++ /dev/null
@@ -1,991 +0,0 @@
-/*
- * Copyright (C) 2001 - 2005 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#ifdef __KERNEL__
-#  include <linux/config.h>
-#  include <linux/module.h>
-#  include <linux/kernel.h>
-#  include <linux/string.h>
-#  include <linux/errno.h>
-#else
-#  include <stdlib.h>
-#  include <errno.h>
-#endif
-
-#include "sys_net.h"
-
-#include "iostream.h"
-#include "lexis.h"
-#include "sxpr_parser.h"
-#include "sys_string.h"
-#include "enum.h"
-
-/** @file
- * Sxpr parsing.
- *
- * So that the parser does not leak memory, all sxprs constructed by
- * the parser must be freed on error.  On successful parse the sxpr
- * returned becomes the responsibility of the caller.
- *
- * @author Mike Wray <mike.wray@hpl.hp.com>
- */
-
-#ifdef DEBUG
-#define dprintf(fmt, args...) IOStream_print(iostdout, "[DEBUG] %s" fmt, __FUNCTION__, ##args)
-#else
-#define dprintf(fmt, args...) do{ }while(0)
-#endif
-
-#undef printf
-#define printf(fmt, args...)   IOStream_print(iostdout, fmt, ##args)
-
-static int state_start(Parser *p, char c);
-static int begin_start(Parser *p, char c);
-
-#if 0
-/** Print a parse error.
- *
- * @param in parser
- * @param msg format followed by printf arguments
- */
-static void eprintf(Parser *in, char *msg, ...){
-    va_list args;
-    if(in->error_out){
-        va_start(args, msg);
-        IOStream_vprint(in->error_out, msg, args);
-        va_end(args);
-    }
-}
-
-/** Print a parse warning.
- *
- * @param in parser
- * @param msg format followed by printf arguments
- */
-static void wprintf(Parser *in, char *msg, ...){
-    va_list args;
-    if(in->error_out){
-        va_start(args, msg);
-        IOStream_vprint(in->error_out, msg, args);
-        va_end(args);
-    }
-}
-#endif
-
-
-/*============================================================================*/
-
-/** Record defining the message for a parse error. */
-typedef struct {
-    ParseErrorId id;
-    char *message;
-} ParseError;
-
-/** Format for printing parse error messages. */
-#define PARSE_ERR_FMT "parse error> line %3d, column %2d: %s"
-
-/** Message catalog for the parse error codes. */
-static ParseError catalog[] = {
-    { PARSE_ERR_UNSPECIFIED,            "unspecified error" },
-    { PARSE_ERR_NOMEM,                  "out of memory" },
-    { PARSE_ERR_UNEXPECTED_EOF,         "unexpected end of input" },
-    { PARSE_ERR_TOKEN_TOO_LONG,         "token too long" },
-    { PARSE_ERR_INVALID_SYNTAX,         "syntax error" },
-    { PARSE_ERR_INVALID_ESCAPE,         "invalid escape" },
-    { 0, NULL }
-};
-
-/** Number of entries in the message catalog. */
-const static int catalog_n = sizeof(catalog)/sizeof(ParseError);
-
-/** Set the parser error stream.
- * Parse errors are reported on the the error stream if it is non-null.
- * 
- * @param z parser
- * @param error_out error stream
- */
-void Parser_set_error_stream(Parser *z, IOStream *error_out){
-    z->error_out = error_out;
-}
-
-/** Get the parser error message for an error code.
- *
- * @param id error code
- * @return error message (empty string if the code is unknown)
- */
-static char *get_message(ParseErrorId id){
-    int i;
-    for(i = 0; i < catalog_n; i++){
-        if(id == catalog[i].id){
-            return catalog[i].message;
-        }
-    }
-    return "";
-}
-
-#if 0
-/** Get the line number.
- *
- * @param in parser
- */
-static int get_line(Parser *in){
-    return in->line_no;
-}
-
-/** Get the column number.
- *
- * @param in parser
- */
-static int get_column(Parser *in){
-    return in->char_no;
-}
-#endif
-
-/** Get the line number the current token started on.
- *
- * @param in parser
- */
-static int get_tok_line(Parser *in){
-    return in->tok_begin_line;
-}
-
-/** Get the column number the current token started on.
- *
- * @param in parser
- */
-static int get_tok_column(Parser *in){
-    return in->tok_begin_char;
-}
-
-/** Return the current token.
- * The return value points at the internal buffer, so
- * it must not be modified (or freed). Use copy_token() if you need a copy.
- *
- * @param p parser
- * @return token
- */
-char *peek_token(Parser *p){
-    return p->tok;
-}
-
-int token_len(Parser *p){
-    return p->tok_end - p->tok;
-}
-
-/** Return a copy of the current token.
- * The returned value should be freed when finished with.
- *
- * @param p parser
- * @return copy of token
- */
-char *copy_token(Parser *p){
-    int n = token_len(p);
-    char *buf = allocate(n + 1);
-    if(buf){
-        memcpy(buf, peek_token(p), n);
-        buf[n] = '\0';
-    }
-    return buf;
-}
-
-void new_token(Parser *p){
-    memset(p->buf, 0, p->buf_end - p->buf);
-    p->tok = p->buf;
-    p->tok_end = p->tok;
-    p->tok_begin_line = p->line_no;
-    p->tok_begin_char = p->char_no;
-}
-
-/** Report a parse error.
- * Does nothing if the error stream is null or there is no error.
- *
- * @param in parser
- */
-static void report_error(Parser *in){
-    if(in->error_out && in->err){
-        char *msg = get_message(in->err);
-        char *tok = peek_token(in);
-        IOStream_print(in->error_out, PARSE_ERR_FMT,
-                       get_tok_line(in), get_tok_column(in), msg);
-        if(tok && tok[0]){
-            IOStream_print(in->error_out, " '%s'", tok);
-        }
-        IOStream_print(in->error_out, "\n");
-    }
-}
-
-/** Get the error message for the current parse error code.
- * Does nothing if there is no error.
- *
- * @param in parser
- * @param buf where to place the message
- * @param n maximum number of characters to place in buf
- * @return current error code (zero for no error)
- */
-int Parser_error_message(Parser *in, char *buf, int n){
-    if(in->err){
-        char *msg = get_message(in->err);
-        snprintf(buf, n, PARSE_ERR_FMT, get_tok_line(in),
-                 get_tok_column(in), msg);
-    }
-    return in->err;
-}
-
-/** Flag a parse error. All subsequent reads will fail.
- * Does not change the parser error code if it is already set.
- *
- * @param in parser
- * @param id error code
- */
-int Parser_error_id(Parser *in, ParseErrorId id){
-    if(!in->err){
-        in->err = id;
-        report_error(in);
-    }
-    return -EINVAL;
-}
-
-/** Flag an unspecified parse error.
- *
- * @param in parser
- */
-int Parser_error(Parser *in){
-    return Parser_error_id(in, PARSE_ERR_INVALID_SYNTAX);
-}
-
-/** Test if the parser's error flag is set.
- *
- * @param in parser
- * @return 1 if set, 0 otherwise
- */
-int Parser_has_error(Parser *in){
-    return (in->err > 0);
-}
-
-/** Test if the parser is at end of input.
- *
- * @param in parser
- * @return 1 if at EOF, 0 otherwise
- */
-int Parser_at_eof(Parser *p){
-    return p->eof;
-}
-
-void ParserState_free(ParserState *z){
-    if(!z) return;
-    objfree(z->val);
-    deallocate(z);
-}
-
-int ParserState_new(ParserStateFn *fn, char *name,
-                    ParserState *parent, ParserState **val){
-    int err = -ENOMEM;
-    ParserState *z;
-    z = ALLOCATE(ParserState);
-    if(!z) goto exit;
-    z->name = name;
-    z->fn = fn;
-    z->parent = parent;
-    z->val = ONULL;
-    err = 0;
-  exit:
-    *val = (err ? NULL : z);
-    return err;
-}
-
-void Parser_pop(Parser *p){
-    ParserState *s = p->state;
-    if(!s) return;
-    p->state = s->parent;
-    if (p->start_state == s) {
-        p->start_state = NULL;
-    }
-    ParserState_free(s);
-}
-
-/** Free a parser.
- * No-op if the parser is null.
- *
- * @param z parser 
- */
-void Parser_free(Parser *z){
-    if(!z) return;
-    // Hmmm. Need to free states, but careful about double free of values.
-    while(z->state){
-        objfree(z->state->val);
-        Parser_pop(z);
-    }
-    if(z->buf) deallocate(z->buf);
-    objfree(z->val);
-    z->val = ONONE;
-    deallocate(z);
-}
-
-int Parser_push(Parser *p, ParserStateFn *fn, char *name){
-    return ParserState_new(fn, name, p->state, &p->state);
-}
-        
-int Parser_return(Parser *p){
-    int err = 0;
-    Sxpr val = ONONE;
-    if(!p->state){
-        err = -EINVAL;
-        goto exit;
-    }
-    val = p->state->val;
-    p->state->val = ONONE;
-    Parser_pop(p);
-    if(p->state){
-        err = cons_push(&p->state->val, val);
-    } else {
-        val = nrev(val);
-        p->val = val;
-    }
-  exit:
-    if(err){
-        objfree(val);
-    }
-    return err;
-}
-
-/** Reset the fields of a parser to initial values.
- *
- * @param z parser
- */
-static void reset(Parser *z){
-    // leave flags
-    // leave error_out
-    while(z->state){
-        Parser_pop(z);
-    }
-    z->val = ONONE;
-    z->eof = 0;
-    z->err = 0;
-    z->line_no = 1;
-    z->char_no = 0;
-    memset(z->buf, 0, z->buf_end - z->buf);
-    z->tok = z->buf;
-    z->tok_end = z->tok;
-    z->tok_begin_line = 0;
-    z->tok_begin_char = 0;
-    z->start_state = NULL;
-}
-
-/** Create a new parser. The error stream defaults to null.
- */
-Parser * Parser_new(void){
-    Parser *z = ALLOCATE(Parser);
-    int n = PARSER_BUF_SIZE;
-    int err = -ENOMEM;
-  
-    if(!z) goto exit;
-    z->buf = allocate(n);
-    if(!z->buf) goto exit;
-    err = 0;
-    z->buf_end = z->buf + n;
-    z->begin = begin_start;
-    reset(z);
-  exit:
-    if(err){
-        Parser_free(z);
-        z = NULL;
-    }
-    return z;
-}
-
-/** Get the next character.
- * Records the character read in the parser,
- * and sets the line and character counts.
- *
- * @param p parser
- * @return error flag: 0 on success, non-zero on error
- */
-static int input_char(Parser *p, char c){
-    int err = 0;
-    if(c=='\n'){
-        p->line_no++;
-        p->char_no = 0;
-    } else {
-        p->char_no++;
-    }
-    return err;
-}
-
-int save_char(Parser *p, char c){
-    int err = 0;
-    if(p->tok_end >= p->buf_end){
-        int buf_n = (p->buf_end - p->buf) + PARSER_BUF_INCREMENT;
-        char *buf = allocate(buf_n);
-        if(!buf){
-            err = -ENOMEM;
-            goto exit;
-        }
-        memcpy(buf, p->buf, p->tok_end - p->buf);
-        p->buf_end = buf + buf_n;
-        p->tok     = buf + (p->tok     - p->buf);
-        p->tok_end = buf + (p->tok_end - p->buf);
-        deallocate(p->buf);
-        p->buf = buf;
-    }
-    *p->tok_end++ = c;
-  exit:
-    return err;
-}
-
-/** Determine if a character is a separator.
- *
- * @param p parser
- * @param c character to test
- * @return 1 if a separator, 0 otherwise
- */
-static int is_separator(Parser *p, char c){
-    return in_sep_class(c);
-}
-
-int Parser_set_value(Parser *p, Sxpr obj){
-    int err = 0;
-    if(NOMEMP(obj)){
-        err = -ENOMEM;
-    } else {
-        p->state->val = obj;
-    }
-    return err;
-}
-    
-int Parser_intern(Parser *p){
-    Sxpr obj = intern(peek_token(p));
-    return Parser_set_value(p, obj);
-}
-
-int Parser_atom(Parser *p){
-    Sxpr obj = atom_new(peek_token(p));
-    return Parser_set_value(p, obj);
-}
-
-int Parser_string(Parser *p){
-    Sxpr obj = string_new_n(peek_token(p), token_len(p));
-    return Parser_set_value(p, obj);
-}
-
-int Parser_data(Parser *p){
-    Sxpr obj = string_new_n(peek_token(p), token_len(p));
-    return Parser_set_value(p, obj);
-}
-
-int Parser_uint(Parser *p){
-    unsigned int x = htonl(*(unsigned int *)peek_token(p));
-    return Parser_set_value(p, OINT(x));
-}
-
-static int get_escape(char c, char *d){
-    int err = 0;
-    switch(c){
-    case 'a':            *d = '\a'; break;
-    case 'b':            *d = '\b'; break;
-    case 'f':            *d = '\f'; break;
-    case 'n':            *d = '\n'; break;
-    case 'r':            *d = '\r'; break;
-    case 't':            *d = '\t'; break;
-    case 'v':            *d = '\v'; break;
-    case c_escape:       *d = c_escape; break;
-    case c_single_quote: *d = c_single_quote; break;
-    case c_double_quote: *d = c_double_quote; break;
-    default:
-        err = -EINVAL;
-    }
-    return err;
-}
-
-int Parser_ready(Parser *p){
-    return CONSP(p->val) || (p->start_state && CONSP(p->start_state->val));
-}
-
-Sxpr Parser_get_val(Parser *p){
-    Sxpr v = ONONE;
-    if(CONSP(p->val)){
-    } else if (p->start_state && CONSP(p->start_state->val)){
-        p->val = p->start_state->val;
-        p->val = nrev(p->val);
-        p->start_state->val = ONULL;
-    }  else {
-        goto exit;
-    }
-    Sxpr w = p->val;
-    v = CAR(w);
-    p->val = CDR(w);
-    hfree(w);
-  exit:
-    return v;
-}
-
-Sxpr Parser_get_all(Parser *p){
-    Sxpr v = ONULL;
-    if(CONSP(p->val)){
-        v = p->val;
-        p->val = ONONE;
-    } else if(p->start_state && CONSP(p->start_state->val)){
-        v = p->start_state->val;
-        p->start_state->val = ONULL;
-        v = nrev(v);
-    }
-    return v;
-}
-
-static int state_comment(Parser *p, char c){
-    int err = 0;
-    if(c == '\n' || Parser_at_eof(p)){
-        Parser_pop(p);
-    } else {
-        err = input_char(p, c);
-    }
-    return err;
-}
-
-static int begin_comment(Parser *p, char c){
-    int err = 0;
-    err = Parser_push(p, state_comment, "comment");
-    if(err) goto exit;
-    err = input_char(p, c);
-  exit:
-    return err;
-}
-
-static int end_string(Parser *p){
-    int err = 0;
-    err = Parser_string(p);
-    if(err) goto exit;
-    err = Parser_return(p);
-  exit:
-    return err;
-}
-
-static int octaldone(Parser *p){
-    int err = 0;
-    char d = (char)(p->state->ival & 0xff);
-    Parser_pop(p);
-    err = Parser_input_char(p, d);
-    return err;
-}
-
-static int octaldigit(Parser *p, int d){
-    int err = 0;
-    p->state->ival *= 8;
-    p->state->ival += d; 
-    p->state->count++;
-    if(err) goto exit;
-    if(p->state->ival < 0 || p->state->ival > 0xff){
-        err = Parser_error(p);
-        goto exit;
-    }
-    if(p->state->count == 3){
-        err = octaldone(p);
-    }
-  exit:
-    return err;
-}
-
-static int state_octal(Parser *p, char c){
-    int err = 0;
-    if(Parser_at_eof(p)){
-        err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
-        goto exit;
-    } else if('0' <= c && c <= '7'){
-        err = octaldigit(p, c - '0');
-    } else {
-        err = octaldone(p);
-        if(err) goto exit;
-        Parser_input_char(p, c);
-    }
-  exit:
-    return err;
-}
-
-static int hexdone(Parser *p){
-    int err = 0;
-    char d = (char)(p->state->ival & 0xff);
-    Parser_pop(p);
-    err = Parser_input_char(p, d);
-    return err;
-}
-    
-static int hexdigit(Parser *p, int d){
-    int err = 0;
-    p->state->ival *= 16;
-    p->state->ival += d; 
-    p->state->count++;
-    if(err) goto exit;
-    if(p->state->ival < 0 || p->state->ival > 0xff){
-        err = Parser_error(p);
-        goto exit;
-    }
-    if(p->state->count == 2){
-        err = hexdone(p);
-    }
-  exit:
-    return err;
-}
-    
-static int state_hex(Parser *p, char c){
-    int err = 0;
-    if(Parser_at_eof(p)){
-        err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
-        goto exit;
-    } else if('0' <= c && c <= '9'){
-        err = hexdigit(p, c - '0');
-    } else if('A' <= c && c <= 'F'){
-        err = hexdigit(p, c - 'A' + 10);
-    } else if('a' <= c && c <= 'f'){
-        err = hexdigit(p, c - 'a' + 10);
-    } else if(p->state->count){
-        err = hexdone(p);
-        if(err) goto exit;
-        Parser_input_char(p, c);
-    }
-  exit:
-    return err;
-}
-
-static int state_escape(Parser *p, char c){
-    int err = 0;
-    char d;
-    if(Parser_at_eof(p)){
-        err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
-        goto exit;
-    }
-    if(get_escape(c, &d) == 0){
-        err = save_char(p, d);
-        if(err) goto exit;
-        Parser_pop(p);
-    } else if(c == 'x'){
-        p->state->fn = state_hex;
-        p->state->ival = 0;
-        p->state->count = 0;
-    } else {
-        p->state->fn = state_octal;
-        p->state->ival = 0;
-        p->state->count = 0;
-        err = Parser_input_char(p, c);
-    }
-  exit:
-    return err;
-}
-
-static int state_string(Parser *p, char c){
-    int err = 0;
-    if(Parser_at_eof(p)){
-        err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
-    } else if(c == p->state->delim){
-        err = end_string(p);
-    } else if(c == '\\'){
-        err = Parser_push(p, state_escape, "escape");
-    } else {
-        err = save_char(p, c);
-    }
-    return err;
-}
-
-static int begin_string(Parser *p, char c){
-    int err = 0;
-    err = Parser_push(p, state_string, "string");
-    if(err) goto exit;
-    new_token(p);
-    p->state->delim = c;
-  exit:
-    return err;
-}
-
-static int end_atom(Parser *p){
-    int err = 0;
-    err = Parser_atom(p);
-    if(err) goto exit;
-    err = Parser_return(p);
-  exit:
-    return err;
-}
-
-static int state_atom(Parser *p, char c){
-    int err = 0;
-    if(Parser_at_eof(p)){
-        err = end_atom(p);
-    } else if(is_separator(p, c) ||
-              in_space_class(c) ||
-              in_comment_class(c)){
-        err = end_atom(p);
-        if(err) goto exit;
-        err = Parser_input_char(p, c);
-    } else {
-        err = save_char(p, c);
-    }
-  exit:
-    return err;
-}
-
-static int begin_atom(Parser *p, char c){
-    int err = 0;
-    err = Parser_push(p, state_atom, "atom");
-    if(err) goto exit;
-    new_token(p);
-    err = save_char(p, c);
-  exit:
-    return err;
-}
-
-static int end_data(Parser *p){
-    int err = 0;
-    err = Parser_data(p);
-    if(err) goto exit;
-    err = Parser_return(p);
-  exit:
-    return err;
-}
-
-static int counted_data(Parser *p, char c){
-    int err = 0;
-    err = save_char(p, c);
-    if(err) goto exit;
-    if(token_len(p) == p->state->count){
-        err = end_data(p);
-    }
-  exit:
-    return err;
-}
-
-static int counted_data_count(Parser *p, char c){
-    int err = 0;
-    if(c == p->state->delim){
-        new_token(p);
-        p->state->count = p->state->ival;
-        p->state->fn = counted_data;
-    } else if('0' <= c && c <= '9'){
-        p->state->ival *= 10;
-        p->state->ival += c - '0';
-    } else {
-        err = -EINVAL;
-    }
-    return err;
-}
-
-static int quoted_data(Parser *p, char c){
-    int err = 0;
-    int count = p->state->count;
-    err = save_char(p, c);
-    if(err) goto exit;
-    // Check that buf is longer than delim and
-    // ends with delim. If so, trim delim off and return.
-    if((token_len(p) >= count) &&
-       !memcmp(p->tok_end - count, p->buf, count)){
-        p->tok_end -= count;
-        end_data(p);
-    }
-  exit:
-    return err;
-}
-
-static int quoted_data_delim(Parser *p, char c){
-    // Saves the delim in the token buffer.
-    int err = 0;
-    err = save_char(p, c);
-    if(err) goto exit;
-    if(c == p->state->delim){
-        p->state->fn = quoted_data;
-        p->state->count = token_len(p);
-        // Advance the token pointer past the delim.
-        p->tok = p->tok_end;
-    }
-  exit:
-    return err;
-}
-
-static int state_data(Parser *p, char c){
-    // Quoted data:
-    // <<delim< anything not containing delimiter<delim<
-    // Where 'delim' is anything not containing '<'.
-    // Counted data:
-    // <*nnn..* N bytes
-    // Where nnn... is N in decimal (
-    int err = 0;
-    switch(c){
-    case c_data_count:
-        p->state->delim = c;
-        p->state->fn = counted_data_count;
-        p->state->ival = 0;
-        new_token(p);
-        break;
-    case c_data_quote:
-        p->state->delim = c;
-        p->state->fn = quoted_data_delim;
-        new_token(p);
-        err = save_char(p, c);
-        break;
-    default:
-        err = Parser_error(p);
-        break;
-    }
-    return err;
-}
-
-static int begin_data(Parser *p, char c){
-    int err = 0;
-    err = Parser_push(p, state_data, "data");
-    if(err) goto exit;
-    new_token(p);
-  exit:
-    return err;
-}
-
-static int state_list(Parser *p, char c){
-    int err = 0;
-    dprintf(">\n");
-    if(Parser_at_eof(p)){
-        err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
-    } else if(c == c_list_close){
-        p->state->val = nrev(p->state->val);
-        err = Parser_return(p);
-    } else {
-        err = state_start(p, c);
-    }
-    dprintf("< err=%d\n", err);
-    return err;
-    
-}
-
-static int begin_list(Parser *p, char c){
-    return Parser_push(p, state_list, "list");
-}
-
-static int state_start(Parser *p, char c){
-    int err = 0;
-    dprintf(">\n");
-    if(Parser_at_eof(p)){
-        err = Parser_return(p);
-    } else if(in_space_class(c)){
-        //skip
-    } else if(in_comment_class(c)){
-        begin_comment(p, c);
-    } else if(c == c_list_open){
-        begin_list(p, c);
-    } else if(c == c_list_close){
-        err = Parser_error(p);
-    } else if(in_string_quote_class(c)){
-        begin_string(p, c);
-    } else if(c == c_data_open){
-        begin_data(p, c);
-    } else if(in_printable_class(c)){
-        begin_atom(p, c);
-    } else if(c == 0x04){
-        //ctrl-D, EOT: end-of-text.
-        Parser_input_eof(p);
-    } else {
-        err = Parser_error(p);
-    }
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-int begin_start(Parser *p, char c){
-    int err = 0;
-    dprintf(">\n");
-    err = Parser_push(p, state_start, "start");
-    if(err) goto exit;
-    p->start_state = p->state;
-  exit:
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-int Parser_input_char(Parser *p, char c){
-    int err = 0;
-    if(Parser_at_eof(p)){
-        //skip;
-    } else {
-        input_char(p, c);
-    }
-    if(!p->state){
-        err = p->begin(p, c);
-        if(err) goto exit;
-    }
-    err = p->state->fn(p, c);
-  exit:
-    return err;
-}
-
-int Parser_input_eof(Parser *p){
-    int err = 0;
-    p->eof = 1;
-    err = Parser_input_char(p, IOSTREAM_EOF);
-    return err;
-}
-
-int Parser_input(Parser *p, char *buf, int buf_n){
-    int err = 0;
-    int i = 0;
-    dprintf("> |%s|\n", buf);
-    if(buf_n <= 0){
-        err = Parser_input_eof(p);
-        goto exit;
-    }
-    for(i = 0; i < buf_n; i++){
-        err = Parser_input_char(p, buf[i]);
-        if(err) goto exit;
-    }
-  exit:
-    err = (err < 0 ? err : buf_n);
-    dprintf("< err=%d\n", err);
-    return err;
-}
-
-#ifdef SXPR_PARSER_MAIN
-/* Stuff for standalone testing. */
-
-#include "file_stream.h"
-//#include "string_stream.h"
-
-/** Main program for testing.
- * Parses input and prints it.
- *
- * @param argc number of arguments
- * @param argv arguments
- * @return error code
- */
-int main(int argc, char *argv[]){
-    Parser *pin;
-    int err = 0;
-    char buf[1024];
-    int k;
-    Sxpr obj;
-    int i = 0;
-
-    pin = Parser_new();
-    Parser_set_error_stream(pin, iostdout);
-    dprintf("> parse...\n");
-    while(1){
-        k = fread(buf, 1, 100, stdin);
-        if(k>=0){
-            buf[k+1] = '\0';
-        }
-        err = Parser_input(pin, buf, k);
-        while(Parser_ready(pin)){
-            obj = Parser_get_val(pin);
-            printf("obj %d\n", i++);
-            objprint(iostdout, obj, 0); printf("\n");
-        }
-        if(k <= 0) break;
-    }
-    dprintf("> err=%d\n", err);
-    return 0;
-}
-#endif
diff --git a/tools/libxutil/sxpr_parser.h b/tools/libxutil/sxpr_parser.h
deleted file mode 100644 (file)
index 591ed95..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2001 - 2005 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#ifndef _XUTIL_SXPR_PARSER_H_
-#define _XUTIL_SXPR_PARSER_H_
-
-#include "sxpr.h"
-#include "iostream.h"
-
-/** @file
- * Sxpr parsing definitions.
- */
-
-/** Initial size of a parser input buffer.
- */
-#define PARSER_BUF_SIZE 512
-
-/** Input buffer size increment (when it's full).
- */
-#define PARSER_BUF_INCREMENT 512
-
-struct Parser;
-typedef int ParserStateFn(struct Parser *, char c);
-
-typedef struct ParserState {
-    struct ParserState *parent;
-    Sxpr val;
-    int ival;
-    int count;
-    char delim;
-    ParserStateFn *fn;
-    char *name;
-} ParserState;
-
-typedef struct Parser {
-    /** Initial state function. */
-    ParserStateFn *begin;
-    /** Parse value. */
-    Sxpr val;
-    /** Error reporting stream (null for no reports). */
-    IOStream *error_out;
-    /** End-of-file flag, */
-    int eof;
-    /** Error flag. Non-zero if there has been a read error. */
-    int err;
-    /** Line number on input (from 1). */
-    int line_no;
-    /** Column number of input (reset on new line). */
-    int char_no;
-    /** Buffer for reading tokens. */
-    char *buf;
-    char *buf_end;
-    char *tok;
-    char *tok_end;
-    /** Line the last token started on. */
-    int tok_begin_line;
-    /** Character number the last token started on. */
-    int tok_begin_char;
-    /** Parsing flags. */
-    int flags;
-    ParserState *state;
-    ParserState *start_state;
-} Parser;
-
-/** Parser error codes. */
-typedef enum {
-    PARSE_ERR_NONE=0,
-    PARSE_ERR_UNSPECIFIED,
-    PARSE_ERR_NOMEM,
-    PARSE_ERR_UNEXPECTED_EOF,
-    PARSE_ERR_TOKEN_TOO_LONG,
-    PARSE_ERR_INVALID_SYNTAX,
-    PARSE_ERR_INVALID_ESCAPE,
-} ParseErrorId;
-
-
-/** Parser flags. */
-//enum {
-//};
-
-/** Raise some parser flags.
- *
- * @param in parser
- * @param flags flags mask
- */
-inline static void Parser_flags_raise(Parser *in, int flags){
-    in->flags |= flags;
-}
-
-/** Lower some parser flags.
- *
- * @param in parser
- * @param flags flags mask
- */
-inline static void Parser_flags_lower(Parser *in, int flags){
-    in->flags &= ~flags;
-}
-
-/** Clear all parser flags.
- *
- * @param in parser
- */
-inline static void Parser_flags_clear(Parser *in){
-    in->flags = 0;
-}
-
-extern void Parser_free(Parser *z);
-extern Parser * Parser_new(void);
-extern int Parser_input(Parser *p, char *buf, int buf_n);
-extern int Parser_input_eof(Parser *p);
-extern int Parser_input_char(Parser *p, char c);
-extern void Parser_set_error_stream(Parser *z, IOStream *error_out);
-
-extern int Parser_error_message(Parser *in, char *buf, int n);
-extern int Parser_has_error(Parser *in);
-extern int Parser_at_eof(Parser *in);
-
-extern int Parser_ready(Parser *p);
-extern Sxpr Parser_get_val(Parser *p);
-extern Sxpr Parser_get_all(Parser *p);
-
-/* Internal parser api. */
-void Parser_pop(Parser *p);
-int Parser_push(Parser *p, ParserStateFn *fn, char *name);
-int Parser_return(Parser *p);
-int Parser_at_eof(Parser *p);
-int Parser_error(Parser *in);
-int Parser_set_value(Parser *p, Sxpr val);
-int Parser_intern(Parser *p);
-int Parser_string(Parser *p);
-int Parser_data(Parser *p);
-int Parser_uint(Parser *p);
-
-char *peek_token(Parser *p);
-char *copy_token(Parser *p);
-void new_token(Parser *p);
-int save_char(Parser *p, char c);
-int token_len(Parser *p);
-
-#endif /* ! _XUTIL_SXPR_PARSER_H_ */
diff --git a/tools/libxutil/sys_net.c b/tools/libxutil/sys_net.c
deleted file mode 100644 (file)
index 4143601..0000000
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#include "sys_net.h"
-#include "sys_string.h"
-
-#ifdef __KERNEL__
-#  include <linux/errno.h>
-#else
-#  include <errno.h>
-#endif
-
-/** @file
- * All network data are kept in network order and only converted to
- * host order for display. Network data includes IP addresses, port numbers and
- * network masks.
- */
-
-/** Maximum value for a port. */
-#define PORT_MAX 0xffff
-
-/** Convert a number of bits to a network mask
- * for IP addresses. The number of bits must
- * be in the range 1-31.
- *
- * @param n number of bits to set in the mask
- * @return value with n high bits set (in network order)
- */
-unsigned long bits_to_mask(int n){
-    unsigned long mask = (n ? (1 << 31) : 0);
-    int i;
-    for(i=1; i<n; i++){
-        mask |= (mask >> 1);
-    }
-    return htonl(mask);
-}
-
-/** Convert a network mask to a number of bits.
- *
- * @param mask network mask in network order
- * @return number of bits in mask
- */
-int mask_to_bits(unsigned long mask){
-    // Start with n set to the number of bits in the mask. Then reduce n by
-    // the number of low zero bits in the mask.
-    int n = 32;
-    for(mask = ntohl(mask);
-        (mask & 1)==0 && n>0;
-        mask >>= 1){
-        n--;
-    }
-    return n;
-}
-
-/** Get the index of the first occurrence of a character in a string.
- * Stops at end of string or after n characters.
- *
- * @param s input string
- * @param n maximum number of charactes to search
- * @param c character to look for
- * @return index of first occurrence, -1 if not found
- */
-inline static int indexof(const char *s, int n, char c){
-    int i;
-    for(i=0; i<n && *s; i++, s++){
-        if(*s == c) return i;
-    }
-    return -1;
-}
-
-/** Convert an IPv4 address in dot notation into an unsigned long (in network order).
- *
- * @param s input string
- * @param address where to put the address
- * @return 0 on success, negative on error
- */
-int get_inet_addr(const char *s, unsigned long *address){
-    // Number of bits in a byte.
-    const int BYTE_BITS = 8;
-    // Number of bytes in a word.
-    const int WORD_BYTES = 4;
-    // Max value for a component of an address.
-    const int ADDR_MAX  = 255;
-    // Separator for components of an address.
-    const char dot = '.';
-
-    int n;
-    unsigned long addr = 0;
-    unsigned long v;
-    int i;
-    int err = -EINVAL;
-    // Bit shift for the current byte.
-    int shift = BYTE_BITS * (WORD_BYTES - 1);
-    char buf[64];
-
-    n = strlen(s);
-    if(n >= sizeof(buf)){
-        goto exit;
-    }
-    for(i=0; i < WORD_BYTES; i++){
-        int idx = indexof(s, n, dot);
-        idx = (idx < 0 ? strlen(s) : idx);
-        strncpy(buf, s, idx); buf[idx]='\0';
-        if(convert_atoul(buf, &v)){
-            goto exit;
-        }
-        if(v < 0 || v > ADDR_MAX){
-            goto exit;
-        }
-        addr |= (v << shift);
-        if(idx == n) break;
-        shift -= BYTE_BITS;
-        s += idx+1;
-    }
-    err = 0;
-  exit:
-    addr = htonl(addr);
-    *address = (err ? 0 : addr);
-    return err;
-}
-
-#ifdef __KERNEL__
-/** Convert an address in network order to IPv4 dot notation.
- * The return value is a static buffer which is overwritten on each call.
- *
- * @param inaddr address (in network order)
- * @return address in dot notation
- */
-char *inet_ntoa(struct in_addr inaddr){
-    static char address[16] = {};
-    uint32_t addr = ntohl(inaddr.s_addr);
-    snprintf(address, sizeof(address), "%d.%d.%d.%d",
-            (unsigned)((addr >> 24) & 0xff),
-            (unsigned)((addr >> 16) & 0xff),
-            (unsigned)((addr >>  8) & 0xff),
-            (unsigned)((addr      ) & 0xff));
-    return address;
-}
-
-
-/** Convert a string in IPv4 dot notation to an int in network order.
- *
- * @param address address in dot notation
- * @param inp result of conversion (in network order)
- * @return 0 on success, error code on error
- */
-int inet_aton(const char *address, struct in_addr *inp){
-    int err = 0; 
-    unsigned long addr;
-    
-    err = get_inet_addr(address, &addr);
-    if(err) goto exit;
-    inp->s_addr = addr;
-  exit:
-    return err;
-}
-#endif
-
-/** Convert a hostname or IPv4 address string to an address in network order.
- *
- * @param name input hostname or address string
- * @param address where to put the address
- * @return 0 if address found OK, nonzero otherwise
- */
-int get_host_address(const char *name, unsigned long *address){
-#ifdef __KERNEL__
-    return get_inet_addr(name, address);
-#else
-    struct hostent *host = gethostbyname(name);
-    if(!host){
-        return -EINVAL;
-    }
-    *address = ((struct in_addr *)(host->h_addr))->s_addr;
-    return 0;
-#endif
-}
-
-/** Convert a service name to a port (in network order).
- *
- * @param name service name
- * @param port where to put the port
- * @return 0 if service port found OK, negative otherwise
- */
-int get_service_port(const char *name, unsigned long *port){
-#ifdef __KERNEL__
-    return -ENOSYS;
-#else
-    struct servent *service;
-    service = getservbyname(name, 0);
-    if(!service){
-        return -EINVAL;
-    }
-    *port = service->s_port;
-    return 0;
-#endif
-}
-
-/** Convert a port number (in network order) to a service name.
- *
- * @param port the port number
- * @return service name if found OK, NULL otherwise
- */
-char *get_port_service(unsigned long port){
-#ifdef __KERNEL__
-    return NULL;
-#else
-    struct servent *service = getservbyport(port, 0);
-    return (service ? service->s_name : NULL);
-#endif
-}
-
-/** Convert a decimal integer or service name to a port (in network order).
- *
- * @param s input to convert
- * @param port where to put the port
- * @return 0 if port found OK, -1 otherwise
- */
-int convert_service_to_port(const char *s, unsigned long *port){
-    int err = 0;
-    unsigned long value;
-    if(convert_atoul(s, &value) == 0){
-        int ok = (0 <= value) && (value <= PORT_MAX);
-        if(ok){
-            value = htons((unsigned short)value);
-        } else {
-            err = -EINVAL;
-        }
-    } else {
-        err = get_service_port(s, &value);
-    }
-    *port = (err ? 0: value);
-    return err;
-}
-
-#define MAC_ELEMENT_N  6 // Number of elements in a MAC address.
-#define MAC_DIGIT_N    2 // Number of digits in an element in a MAC address.
-#define MAC_LENGTH    17 //((MAC_ELEMENT_N * MAC_DIGIT_N) + MAC_ELEMENT_N - 1)
-
-/** Convert a mac address from a string of the form
- * XX:XX:XX:XX:XX:XX to numerical form (an array of 6 unsigned chars).
- * Each X denotes a hex digit: 0..9, a..f, A..F.
- * Also supports using '-' as the separator instead of ':'.
- *
- * @param mac_in string to convert
- * @param mac destination for the value
- * @return 0 on success, -1 on error
- */
-int mac_aton(const char *mac_in, unsigned char *mac){
-    int err = 0;
-    int i, j;
-    const char *p;
-    char sep = 0;
-    unsigned char d;
-    if(!mac_in || strlen(mac_in) != MAC_LENGTH){
-        err = -1;
-        goto exit;
-    }
-    for(i = 0, p = mac_in; i < MAC_ELEMENT_N; i++){
-        d = 0;
-        if(i){
-            if(!sep){
-                if(*p == ':' || *p == '-') sep = *p;
-            }
-            if(sep && *p == sep){
-                p++;
-            } else {
-                err = -1;
-                goto exit;
-            }
-        }
-        for(j = 0; j < MAC_DIGIT_N; j++, p++){
-            if(j) d <<= 4;
-            if(*p >= '0' && *p <= '9'){
-                d += (*p - '0');
-            } else if(*p >= 'A' && *p <= 'F'){
-                d += (*p - 'A') + 10;
-            } else if(*p >= 'a' && *p <= 'f'){
-                d += (*p - 'a') + 10;
-            } else {
-                err = -1;
-                goto exit;
-            }
-        }
-        mac[i] = d;
-    }
-  exit:
-    return err;
-}
-
-/** Convert a MAC address from numerical form to a string.
- *
- * @param mac address to convert
- * @return static string value
- */
-char *mac_ntoa(const unsigned char *mac){
-    static char buf[MAC_LENGTH + 1];
-    int buf_n = sizeof(buf);
-
-    memset(buf, 0, buf_n);
-    snprintf(buf, buf_n, "%02x:%02x:%02x:%02x:%02x:%02x",
-             mac[0], mac[1], mac[2],
-             mac[3], mac[4], mac[5]);
-    buf[buf_n - 1] = '\0';
-    return buf;
-}
diff --git a/tools/libxutil/sys_net.h b/tools/libxutil/sys_net.h
deleted file mode 100644 (file)
index 6175494..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XUTIL_SYS_NET_H_
-#define _XUTIL_SYS_NET_H_
-/** @file
- *
- * Replacement for standard network includes.
- * Works in user or kernel code.
- */
-
-extern int get_inet_addr(const char *s, unsigned long *address);
-extern unsigned long bits_to_mask(int n);
-extern int mask_to_bits(unsigned long mask);
-extern int get_host_address(const char *name, unsigned long *address);
-extern int get_service_port(const char *name, unsigned long *port);
-extern char *get_port_service(unsigned long port);
-extern int convert_service_to_port(const char *s, unsigned long *port);
-
-#ifdef __KERNEL__
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <asm/byteorder.h> 
-
-#ifndef htonl
-#define htonl(x) __constant_htonl(x)
-#endif
-
-#ifndef ntohl
-#define ntohl(x) __constant_ntohl(x)
-#endif
-
-#ifndef htons
-#define htons(x) __constant_htons(x)
-#endif
-
-#ifndef ntohs
-#define ntohs(x) __constant_ntohs(x)
-#endif
-
-#include <linux/in.h>
-extern char *inet_ntoa(struct in_addr inaddr);
-extern int inet_aton(const char *address, struct in_addr *inp);
-
-#else
-
-#include <limits.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-
-#endif
-
-extern char *mac_ntoa(const unsigned char *macaddr);
-extern int mac_aton(const char *addr, unsigned char *macaddr);
-
-#endif /* !_XUTIL_SYS_NET_H_ */
-
-
-
diff --git a/tools/libxutil/sys_string.c b/tools/libxutil/sys_string.c
deleted file mode 100644 (file)
index 22a8ae3..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifdef __KERNEL__
-#  include <linux/config.h>
-#  include <linux/module.h>
-#  include <linux/kernel.h>
-#  include <linux/errno.h>
-#else
-#  include <errno.h>
-#endif
-
-#include "allocate.h"
-#include "sys_string.h"
-
-/** Set the base to use for converting a string to a number.  Base is
- * hex if starts with 0x, otherwise decimal.
- *
- * @param s input string
- * @param base where to put the base
- * @return rest of s to parse as a number
- */
-inline static const char * convert_set_base(const char *s, int *base){
-    *base = 10;
-    if(s){
-        if(*s=='0'){
-            s++;
-            if(*s=='x' || *s=='X'){
-                *base = 16;
-                s++;
-            }
-        }
-    }
-    return s;
-}
-
-/** Set the sign to use for converting a string to a number.
- * Value is 1 for positive, -1 for negative.
- *
- * @param s input string
- * @param sign where to put the sign
- * @return rest of s to parse as a number
- */
-inline static const char * convert_set_sign(const char *s, int *sign){
-    *sign = 1;
-    if(s){
-        if(*s == '+'){
-            *sign = 1;
-            s++;
-        } else if (*s == '-'){
-            *sign = -1;
-            s++;
-        }
-    }
-    return s;
-}
-
-/** Get the numerical value of a digit in the given base.
- *
- * @param c digit character
- * @param base to use
- * @return numerical value of digit in range 0..base-1 or
- * -1 if not in range for the base
- */
-inline static int convert_get_digit(char c, int base){
-    int d;
-
-    if('0'<=c  && c<='9'){
-        d = c - '0';
-    } else if('a'<=c && c<='f'){
-        d = c - 'a' + 10;
-    } else if('A'<=c && c<='F'){
-        d = c - 'A' + 10;
-    } else {
-        d = -1;
-    }
-    return (d < base ? d : -1);
-}
-
-/** Convert a string to an unsigned long by parsing it as a number.
- * Will accept hex or decimal in usual C syntax.
- *
- * @param str input string
- * @param val where to put the result
- * @return 0 if converted OK, negative otherwise
- */
-int convert_atoul(const char *str, unsigned long *val){
-    int err = 0;
-    unsigned long v = 0;
-    int base;
-    const char *s = str;
-
-    if(!s) {
-        err = -EINVAL;
-        goto exit;
-    }
-    s = convert_set_base(s, &base);
-    for( ; !err && *s; s++){
-        int digit = convert_get_digit(*s, base);
-        if(digit<0){
-            err = -EINVAL;
-            goto exit;
-        }
-        v *= base;
-        v += digit;
-    } 
-  exit:
-    *val = (err ? 0 : v);
-    return err;
-}
-
-/** Convert a string to a long by parsing it as a number.
- * Will accept hex or decimal in usual C syntax.
- *
- * @param str input string
- * @param val where to put the result
- * @return 0 if converted OK, negative otherwise
- */
-int convert_atol(const char *str, long *val){
-    int err = 0;
-    unsigned long v = 0;
-    int base, sign = 1;
-    const char *s = str;
-
-    if(!s) {
-        err = -EINVAL;
-        goto exit;
-    }
-    s = convert_set_sign(s, &sign);
-    s = convert_set_base(s, &base);
-    for( ; !err && *s; s++){
-        int digit = convert_get_digit(*s, base);
-        if(digit<0){
-            err = -EINVAL;
-            goto exit;
-        }
-        v *= base;
-        v += digit;
-    } 
-    if(sign < 0) v = -v;
-  exit:
-    *val = (err ? 0 : v);
-    return err;
-}
-
-/** Combine a directory path with a relative path to produce
- * a new path.
- *
- * @param s directory path
- * @param t relative path
- * @return new combined path s/t
- */
-int path_concat(char *s, char *t, char **val){
-    int err = 0;
-    int sn, tn, vn;
-    char *v;
-    sn = strlen(s);
-    if(sn > 0 && s[sn-1] == '/'){
-        sn--;
-    }
-    tn = strlen(t);
-    if(tn > 0 && t[0] == '/'){
-        tn--;
-    }
-    vn = sn+tn+1;
-    v = (char*)allocate(vn+1);
-    if(!v){
-        err = -ENOMEM;
-        goto exit;
-    }
-    strncpy(v, s, sn);
-    v[sn] = '/';
-    strncpy(v+sn+1, t, tn);
-    v[vn] = '\0';
-  exit:
-    *val = (err ? NULL : v);
-    return err;    
-}
diff --git a/tools/libxutil/sys_string.h b/tools/libxutil/sys_string.h
deleted file mode 100644 (file)
index 88d9d8d..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef _XUTIL_SYS_STRING_H_
-#define _XUTIL_SYS_STRING_H_
-/** @file
- * Replacement for standard string includes.
- * Works in user or kernel code.
- */
-/*============================================================================*/
-#ifdef __KERNEL__
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <stdarg.h>
-#include "allocate.h"
-
-#if 0
-static inline int tolower(int c){
-    return (c>='A' && c<='Z' ? (c-'A')+'a' : c);
-}
-#endif
-
-static inline int isalpha(int c){
-    return (c>='A' && c<='Z') || (c>='a' && c<='z');
-}
-
-static inline int isdigit(int c){
-   return (c>='0' && c<='9');
-}
-
-#if 0
-static inline int strcasecmp(const char *s1, const char *s2){
-       int c1, c2;
-
-       do {
-               c1 = tolower(*s1++);
-               c2 = tolower(*s2++);
-       } while (c1 && c1 == c2);
-       return c1 - c2;
-}
-#endif
-
-static inline char * strdup(const char *s){
-    int n = (s ? 1+strlen(s) : 0);
-    char *copy = (n ? allocate(n) : NULL);
-    if(copy){
-        strcpy(copy, s);
-    }
-    return copy;
-}
-
-/*============================================================================*/
-#else
-#include <string.h>
-#include <stdio.h>
-
-#ifndef _GNU_SOURCE
-static inline size_t strnlen(const char *s, size_t n){
-    int k = 0;
-    if(s){
-       for(k=0; *s && k<n; s++, k++){}
-    }
-    return k;
-}
-#endif
-
-#endif
-/*============================================================================*/
-
-extern int convert_atoul(const char *s, unsigned long *v);
-extern int convert_atol(const char *s, long *v);
-extern int path_concat(char *s, char *t, char **val);
-
-#endif /* !_XUTIL_SYS_STRING_H_ */
diff --git a/tools/libxutil/util.c b/tools/libxutil/util.c
deleted file mode 100644 (file)
index 0ac388b..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2002 - 2004 Mike Wray <mike.wray@hp.com>.
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#include "sys_net.h"
-#include "sys_string.h"
-
-#ifndef __KERNEL__
-#  include <grp.h>   
-#  include <pwd.h>  
-#endif
-
-#include "util.h"
-
-
-/** @file Various utility functions.
- */
-
-/** Print an address (in network order) as an IPv4 address string
- * in dot notation.
- *
- * @param io where to print address
- * @param address to print (in network order)
- * @return bytes printed
- */
-int print_address(IOStream *io, unsigned long address){
-#ifdef __KERNEL__
-    address = ntohl(address);
-    return IOStream_print(io, "%u.%u.%u.%u", 
-                          (unsigned)((address >> 24) & 0xff),
-                          (unsigned)((address >> 16) & 0xff),
-                          (unsigned)((address >>  8) & 0xff),
-                          (unsigned)((address      ) & 0xff));
-#else
-    struct in_addr inaddr = { s_addr: address };
-    return IOStream_print(io, inet_ntoa(inaddr));
-#endif
-}
-
-/** Get the protocol number for a protocol.
- *
- * @param name protocol name
- * @param protocol where to put the protocol number
- * @return 0 if OK, error otherwise
- */  
-int get_protocol_number(char *name, unsigned long *protocol){
-#ifdef __KERNEL__
-    return -1;
-#else
-    struct protoent *proto = getprotobyname(name);
-    if(!proto){
-       return -1;
-    }
-    *protocol = proto->p_proto;
-    return 0;
-#endif
-}
-
-/** Get the protocol name for a protocol number.
- *
- * @param protocol number
- * @return name or null
- */
-char *get_protocol_name(unsigned long protocol){
-#ifdef __KERNEL__
-    return 0;
-#else
-    struct protoent *proto = getprotobynumber(protocol);
-    if(!proto){
-       return 0;
-    }
-    return proto->p_name;
-#endif
-}
-
-/** Get the host name for an address.
- *
- * @param addr address
- * @return host name or null
- */
-char *get_host_name(unsigned long addr){
-#ifdef __KERNEL__
-    return 0;
-#else
-    struct in_addr inaddr;
-    struct hostent *host = 0;
-
-    inaddr.s_addr = addr;
-    host = gethostbyaddr((char*)&inaddr, sizeof(inaddr), AF_INET);
-    if(!host) return NULL;
-    return host->h_name;
-#endif
-}
diff --git a/tools/libxutil/util.h b/tools/libxutil/util.h
deleted file mode 100644 (file)
index b4a1705..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2002 - 2004 Mike Wray <mike.wray@hp.com>.
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or  (at your option) any later version. This library is 
- * distributed in the  hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#ifndef _XEN_LIB_UTIL_H_
-#define _XEN_LIB_UTIL_H_
-
-#include "iostream.h"
-
-extern int print_address(IOStream *io, unsigned long address);
-extern int get_protocol_number(char *name, unsigned long *protocol);
-extern char *get_protocol_name(unsigned long protocol);
-extern char *get_host_name(unsigned long addr);
-
-#endif /* ! _XEN_LIB_UTIL_H_ */
index 43e68949c24314c337a37404b0c58686d7f45de9..5281e94e006831e59cef6aa6daf8093e9fa4a46a 100644 (file)
@@ -45,4 +45,4 @@ clean:
        $(CC) -c $(CFLAGS) -o $@ $<
 
 $(TARGETS): %: %.o Makefile
-       $(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxc -L$(XEN_LIBXUTIL) -lxutil
+       $(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxc
index 92b334fe7a1ab834431058253eee01e39b37dda4..c33e7d925080fb72f5afcc792ddb48ef4d376ff5 100644 (file)
@@ -38,7 +38,7 @@ clean:
        $(CC) $(CFLAGS) -o $@ $<
 
 cpuperf-xen: cpuperf.c $(HDRS) Makefile
-       $(CC) $(CFLAGS) -I $(XEN_LIBXC) -L$(XEN_LIBXC) -lxc -L$(XEN_LIBXUTIL) -lxutil -DXENO -o $@ $<
+       $(CC) $(CFLAGS) -I $(XEN_LIBXC) -L$(XEN_LIBXC) -lxc -DXENO -o $@ $<
 
 cpuperf-perfcntr: cpuperf.c $(HDRS) Makefile
        $(CC) $(CFLAGS) -DPERFCNTR -o $@ $<
index 0a2fde5f9c525850386dc803200bdbac57e237bd..76861908a6ee5c828990c9b3ea239b3cdea4d604 100644 (file)
@@ -9,15 +9,13 @@ extra_compile_args  = [ "-fno-strict-aliasing", "-Wall", "-Werror" ]
 
 include_dirs = [ XEN_ROOT + "/tools/python/xen/lowlevel/xu",
                  XEN_ROOT + "/tools/libxc",
-                 XEN_ROOT + "/tools/libxutil",
                  XEN_ROOT + "/tools/xcs",
                  ]
 
 library_dirs = [ XEN_ROOT + "/tools/libxc",
-                 XEN_ROOT + "/tools/libxutil",
                  ]
 
-libraries = [ "xc", "xutil" ]
+libraries = [ "xc" ]
 
 xc = Extension("xc",
                extra_compile_args = extra_compile_args,
index 653d7c01d166c4e804934d2910d94d47f3191774..c23bc461e12eef36af07054cf3e679721c9768fa 100644 (file)
@@ -15,7 +15,6 @@
 #include <netdb.h>
 #include <arpa/inet.h>
 #include "xc_private.h"
-#include "gzip_stream.h"
 #include "linux_boot_params.h"
 
 /* Needed for Python versions earlier than 2.3. */
index d4d8183130755d1ea7a2f515ebe7223faa3e6514..a5156c4687cad359a79ef1113a2deced8781ef77 100644 (file)
@@ -7,11 +7,11 @@ export prefix?=$(shell cd ../../dist/install && pwd)
 
 .PHONY: all compile
 .PHONY: gc-install gc-clean gc-prstine
-.PHONY: vnetd vnet-module install dist clean pristine
+.PHONY: libxutil vnetd vnet-module install dist clean pristine
 
 all: compile
 
-compile: vnetd vnet-module
+compile: libxutil vnetd vnet-module
 #compile: vnet-module
 
 gc.tar.gz:
@@ -32,6 +32,9 @@ gc-clean:
 gc-pristine:
        -rm -rf gc?.? gc
 
+libxutil:
+       $(MAKE) -C libxutil
+
 vnetd: gc-install
        $(MAKE) -C vnetd
 
@@ -39,13 +42,15 @@ vnet-module:
        $(MAKE) -C vnet-module
 
 install: compile
+       $(MAKE) -C libxutil install
        $(MAKE) -C vnetd install
        $(MAKE) -C vnet-module install
        $(MAKE) -C examples install
 
 clean:
+       -$(MAKE) -C libxutil clean
        -$(MAKE) -C vnetd clean
        -$(MAKE) -C vnet-module clean
        -rm -rf gc?.? gc
-       
+
 pristine: clean gc-pristine
diff --git a/tools/vnet/libxutil/Makefile b/tools/vnet/libxutil/Makefile
new file mode 100644 (file)
index 0000000..5e9adaa
--- /dev/null
@@ -0,0 +1,77 @@
+
+XEN_ROOT = ../../..
+INSTALL                = install
+INSTALL_DATA   = $(INSTALL) -m0644
+INSTALL_PROG   = $(INSTALL) -m0755
+INSTALL_DIR    = $(INSTALL) -d -m0755
+
+include $(XEN_ROOT)/tools/Rules.mk
+
+LIB_SRCS :=
+LIB_SRCS += allocate.c
+LIB_SRCS += enum.c
+LIB_SRCS += file_stream.c
+LIB_SRCS += gzip_stream.c
+LIB_SRCS += hash_table.c
+LIB_SRCS += iostream.c
+LIB_SRCS += lexis.c
+LIB_SRCS += string_stream.c
+LIB_SRCS += sxpr.c
+LIB_SRCS += sxpr_parser.c
+LIB_SRCS += sys_net.c
+LIB_SRCS += sys_string.c
+LIB_SRCS += util.c
+
+LIB_OBJS := $(LIB_SRCS:.c=.o)
+PIC_OBJS := $(LIB_SRCS:.c=.opic)
+
+CFLAGS   += -Wall -Werror -O3 -fno-strict-aliasing
+
+# Get gcc to generate the dependencies for us.
+CFLAGS   += -Wp,-MD,.$(@F).d
+DEPS     = .*.d
+
+MAJOR    := 3.0
+MINOR    := 0
+LIB      := libxutil.so 
+LIB      += libxutil.so.$(MAJOR)
+LIB      += libxutil.so.$(MAJOR).$(MINOR)
+LIB      += libxutil.a
+
+all: build
+build: check-for-zlib
+       $(MAKE) $(LIB)
+
+libxutil.so: libxutil.so.$(MAJOR)
+       ln -sf $^ $@
+
+libxutil.so.$(MAJOR): libxutil.so.$(MAJOR).$(MINOR)
+       ln -sf $^ $@
+
+libxutil.so.$(MAJOR).$(MINOR): $(PIC_OBJS)
+       $(CC) $(CFLAGS) -Wl,-soname -Wl,libxutil.so.$(MAJOR) -shared -o $@ $^
+
+libxutil.a: $(LIB_OBJS)
+       $(AR) rc $@ $^
+
+check-for-zlib:
+       @if [ ! -e /usr/include/zlib.h ]; then \
+       echo "***********************************************************"; \
+       echo "ERROR: install zlib header files (http://www.gzip.org/zlib)"; \
+       echo "***********************************************************"; \
+       false; \
+       fi
+
+install: build
+       [ -d $(DESTDIR)/usr/$(LIBDIR) ] || $(INSTALL_DIR) -p $(DESTDIR)/usr/$(LIBDIR)
+       $(INSTALL_PROG) libxutil.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)
+       $(INSTALL_DATA) libxutil.a $(DESTDIR)/usr/$(LIBDIR)
+       ln -sf libxutil.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)/libxutil.so.$(MAJOR)
+       ln -sf libxutil.so.$(MAJOR) $(DESTDIR)/usr/$(LIBDIR)/libxutil.so
+
+clean:
+       $(RM) *.a *.so* *.o *.opic *.rpm 
+       $(RM) *~
+       $(RM) $(DEPS)
+
+-include $(DEPS)
diff --git a/tools/vnet/libxutil/allocate.c b/tools/vnet/libxutil/allocate.c
new file mode 100644 (file)
index 0000000..600ebab
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "allocate.h"
+
+/** @file
+ * Support for allocating memory.
+ * Usable from user code or kernel code (with __KERNEL__ defined).
+ * In user code will use GC if USE_GC is defined.
+ */
+
+#ifdef __KERNEL__
+/*----------------------------------------------------------------------------*/
+#  include <linux/config.h>
+#  include <linux/slab.h>
+#  include <linux/string.h>
+#  include <linux/types.h>
+
+#  define DEFAULT_TYPE    0
+#  define MALLOC(n, type) kmalloc(n, type)
+#  define FREE(ptr)       kfree(ptr)
+
+/*----------------------------------------------------------------------------*/
+#else /* ! __KERNEL__ */
+
+#  include <stdlib.h>
+#  include <string.h>
+
+#  define DEFAULT_TYPE    0
+
+#ifdef USE_GC
+#  include "gc.h"
+#  define MALLOC(n, typ)  GC_malloc(n)
+#  define FREE(ptr)       (ptr=NULL)
+//typedef void *GC_PTR;
+//GC_PTR (*GC_oom_fn)(size_t n);
+#else
+#  define MALLOC(n, type) malloc(n)
+#  define FREE(ptr)       free(ptr)
+#endif
+
+/*----------------------------------------------------------------------------*/
+#endif
+
+/** Function to call when memory cannot be allocated. */
+AllocateFailedFn *allocate_failed_fn = NULL;
+
+/** Allocate memory and zero it.
+ * The type is only relevant when calling from kernel code,
+ * from user code it is ignored.
+ * In kernel code the values accepted by kmalloc can be used:
+ * GFP_USER, GFP_ATOMIC, GFP_KERNEL.
+ *
+ * @param size number of bytes to allocate
+ * @param type memory type to allocate (kernel only)
+ * @return pointer to the allocated memory or zero
+ * if malloc failed
+ */
+void *allocate_type(int size, int type){
+    void *p = MALLOC(size, type);
+    if(p){
+        memzero(p, size);
+    } else if(allocate_failed_fn){
+        allocate_failed_fn(size, type);
+    }
+    return p;
+}
+
+/** Allocate memory and zero it.
+ *
+ * @param size number of bytes to allocate
+ * @return pointer to the allocated memory or zero
+ * if malloc failed
+ */
+void *allocate(int size){
+    return allocate_type(size, DEFAULT_TYPE);
+}
+
+/** Free memory allocated by allocate().
+ * No-op if 'p' is null.
+ *
+ * @param p memory to free
+ */
+void deallocate(void *p){
+    if(p){
+        FREE(p);
+    }
+}
+
+/** Set bytes to zero.
+ * No-op if 'p' is null.
+ *
+ * @param p memory to zero
+ * @param size number of bytes to zero
+ */
+void memzero(void *p, int size){
+    if(p){
+        memset(p, 0, (size_t)size);
+    }
+}
+
diff --git a/tools/vnet/libxutil/allocate.h b/tools/vnet/libxutil/allocate.h
new file mode 100644 (file)
index 0000000..391b7be
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _XUTIL_ALLOCATE_H_
+#define _XUTIL_ALLOCATE_H_
+
+/** Allocate memory for a given type, and cast. */
+#define ALLOCATE(ctype) (ctype *)allocate(sizeof(ctype))
+
+/** Allocate memory for a given type, and cast. */
+#define ALLOCATE_TYPE(ctype, type) (ctype *)allocate(sizeof(ctype))
+
+extern void *allocate_type(int size, int type);
+extern void *allocate(int size);
+extern void deallocate(void *);
+extern void memzero(void *p, int size);
+
+typedef void AllocateFailedFn(int size, int type);
+extern AllocateFailedFn *allocate_failed_fn;
+
+#endif /* _XUTIL_ALLOCATE_H_ */
+
+
+
+
+
+
+
+
+
diff --git a/tools/vnet/libxutil/debug.h b/tools/vnet/libxutil/debug.h
new file mode 100644 (file)
index 0000000..1f5a19d
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef _XUTIL_DEBUG_H_
+#define _XUTIL_DEBUG_H_
+
+#ifndef MODULE_NAME
+#define MODULE_NAME ""
+#endif
+
+#ifdef __KERNEL__
+#include <linux/config.h>
+#include <linux/kernel.h>
+
+#ifdef DEBUG
+
+#define dprintf(fmt, args...) printk(KERN_DEBUG   "[DBG] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args)
+#define wprintf(fmt, args...) printk(KERN_WARNING "[WRN] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args)
+#define iprintf(fmt, args...) printk(KERN_INFO    "[INF] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args)
+#define eprintf(fmt, args...) printk(KERN_ERR     "[ERR] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args)
+
+#else
+
+#define dprintf(fmt, args...) do {} while(0)
+#define wprintf(fmt, args...) printk(KERN_WARNING "[WRN] " MODULE_NAME fmt, ##args)
+#define iprintf(fmt, args...) printk(KERN_INFO    "[INF] " MODULE_NAME fmt, ##args)
+#define eprintf(fmt, args...) printk(KERN_ERR     "[ERR] " MODULE_NAME fmt, ##args)
+
+#endif
+
+#else
+
+#include <stdio.h>
+
+#ifdef DEBUG
+
+#define dprintf(fmt, args...) fprintf(stdout, "%d [DBG] " MODULE_NAME ">%s" fmt, getpid(), __FUNCTION__, ##args)
+#define wprintf(fmt, args...) fprintf(stderr, "%d [WRN] " MODULE_NAME ">%s" fmt, getpid(),__FUNCTION__, ##args)
+#define iprintf(fmt, args...) fprintf(stderr, "%d [INF] " MODULE_NAME ">%s" fmt, getpid(),__FUNCTION__, ##args)
+#define eprintf(fmt, args...) fprintf(stderr, "%d [ERR] " MODULE_NAME ">%s" fmt, getpid(),__FUNCTION__, ##args)
+
+#else
+
+#define dprintf(fmt, args...) do {} while(0)
+#define wprintf(fmt, args...) fprintf(stderr, "%d [WRN] " MODULE_NAME fmt, getpid(), ##args)
+#define iprintf(fmt, args...) fprintf(stderr, "%d [INF] " MODULE_NAME fmt, getpid(), ##args)
+#define eprintf(fmt, args...) fprintf(stderr, "%d [ERR] " MODULE_NAME fmt, getpid(), ##args)
+
+#endif
+
+#endif
+
+/** Print format for an IP address.
+ * See NIPQUAD(), HIPQUAD()
+ */
+#define IPFMT "%u.%u.%u.%u"
+
+#endif /* ! _XUTIL_DEBUG_H_ */
diff --git a/tools/vnet/libxutil/enum.c b/tools/vnet/libxutil/enum.c
new file mode 100644 (file)
index 0000000..95f6e31
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2002, 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or  (at your option) any later version. This library is 
+ * distributed in the  hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#ifdef __KERNEL__
+#include <linux/errno.h>
+#else
+#include <errno.h>
+#endif
+
+#include "sys_string.h"
+#include "enum.h"
+
+/** Map an enum name to its value using a table.
+ *
+ * @param name enum name
+ * @param defs enum definitions
+ * @return enum value or -1 if not known
+ */
+int enum_name_to_val(char *name, EnumDef *defs){
+    int val = -1;
+    for(; defs->name; defs++){
+       if(!strcmp(defs->name, name)){
+           val = defs->val;
+           break;
+       }
+    }
+    return val;
+}
+
+/** Map an enum value to its name using a table.
+ *
+ * @param val enum value
+ * @param defs enum definitions
+ * @param defs_n number of definitions
+ * @return enum name or NULL if not known
+ */
+char *enum_val_to_name(int val, EnumDef *defs){
+    char *name = NULL;
+    for(; defs->name; defs++){
+       if(val == defs->val){
+           name = defs->name;
+           break;
+       }
+    }
+    return name;
+}
+
diff --git a/tools/vnet/libxutil/enum.h b/tools/vnet/libxutil/enum.h
new file mode 100644 (file)
index 0000000..cdc0f6f
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2002, 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or  (at your option) any later version. This library is 
+ * distributed in the  hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#ifndef _XUTIL_ENUM_H_
+#define _XUTIL_ENUM_H_
+
+/** Mapping of an enum value to a name. */
+typedef struct EnumDef {
+    int val;
+    char *name;
+} EnumDef;
+
+extern int enum_name_to_val(char *name, EnumDef *defs);
+extern char *enum_val_to_name(int val, EnumDef *defs);
+
+#endif /* _XUTIL_ENUM_H_ */
diff --git a/tools/vnet/libxutil/fd_stream.c b/tools/vnet/libxutil/fd_stream.c
new file mode 100644 (file)
index 0000000..428f0a5
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/** @file
+ * An IOStream implementation using fds.
+ */
+#ifndef __KERNEL__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include "allocate.h"
+#include "fd_stream.h"
+
+#define MODULE_NAME "fd_stream"
+#define DEBUG 1
+//#undef DEBUG
+#include "debug.h"
+
+static int fd_read(IOStream *s, void *buf, size_t n);
+static int fd_write(IOStream *s, const void *buf, size_t n);
+static int fd_error(IOStream *s);
+static int fd_close(IOStream *s);
+static void fd_free(IOStream *s);
+static int fd_flush(IOStream *s);
+
+/** Methods used by a fd IOStream. */
+static const IOMethods fd_methods = {
+    read:  fd_read,
+    write: fd_write,
+    error: fd_error,
+    close: fd_close,
+    free:  fd_free,
+    flush: fd_flush,
+};
+
+/** Get the fd data.
+ * 
+ * @param io fd stream
+ * @return data
+ */
+static inline FDData * fd_data(IOStream *io){
+    return (FDData *)io->data;
+}
+
+/** Test if a stream is a fd stream.
+ *
+ * @param io stream
+ * @return 0 if a fd stream, -EINVAL if not
+ */
+int fd_stream_check(IOStream *io){
+    return (io && io->methods == &fd_methods ? 0 : -EINVAL);
+}
+
+/** Get the data for a fd stream.
+ *
+ * @param io stream
+ * @param data return value for the data
+ * @return 0 if a fd stream, -EINVAL if not
+ */
+int fd_stream_data(IOStream *io, FDData **data){
+    int err = fd_stream_check(io);
+    if(err){
+        *data = NULL;
+    } else {
+        *data = fd_data(io);
+    }
+    return err;
+}
+
+
+/** Write to the underlying fd.
+ *
+ * @param stream input
+ * @param buf where to put input
+ * @param n number of bytes to write
+ * @return number of bytes written
+ */
+static int fd_write(IOStream *s, const void *buf, size_t n){
+    FDData *data = fd_data(s);
+    int k;
+    k = write(data->fd, buf, n);
+    return k;
+}
+
+/** Read from the underlying stream;
+ *
+ * @param stream input
+ * @param buf where to put input
+ * @param n number of bytes to read
+ * @return number of bytes read
+ */
+static int fd_read(IOStream *s, void *buf, size_t n){
+    FDData *data = fd_data(s);
+    int k;
+    k = read(data->fd, buf, n);
+    //printf("> fd_read> buf=%p n=%d --> k=%d\n", buf, n, k);
+    return k;
+}
+
+/** Flush the fd (no-op).
+ *
+ * @param s fd stream
+ * @return 0 on success, error code otherwise
+ */
+static int fd_flush(IOStream *s){
+    return 0;
+}
+
+/** Check if a fd stream has an error (no-op).
+ *
+ * @param s fd stream
+ * @return 1 if has an error, 0 otherwise
+ */
+static int fd_error(IOStream *s){
+    return 0;
+}
+
+/** Close a fd stream.
+ *
+ * @param s fd stream to close
+ * @return result of the close
+ */
+static int fd_close(IOStream *s){
+    FDData *data = fd_data(s);
+    return close(data->fd);
+}
+
+/** Free a fd stream.
+ *
+ * @param s fd stream
+ */
+static void fd_free(IOStream *s){
+    FDData *data = fd_data(s);
+    deallocate(data);
+}
+
+/** Create an IOStream for a fd.
+ *
+ * @param fd fd to wtap
+ * @return new IOStream using fd for i/o
+ */
+IOStream *fd_stream_new(int fd){
+    int err = -ENOMEM;
+    IOStream *io = NULL;
+    FDData *data = NULL;
+
+    io = ALLOCATE(IOStream);
+    if(!io) goto exit;
+    io->methods = &fd_methods;
+    data = ALLOCATE(FDData);
+    if(!data) goto exit;
+    io->data = data;
+    data->fd = fd;
+    err = 0;
+  exit:
+    if(err){
+        if(io){
+            if(data) deallocate(data);
+            deallocate(io);
+            io = NULL;
+        }
+    }
+    return io;
+}
+
+#endif
diff --git a/tools/vnet/libxutil/fd_stream.h b/tools/vnet/libxutil/fd_stream.h
new file mode 100644 (file)
index 0000000..b37a686
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _XMC_FD_STREAM_H_
+#define _XMC_FD_STREAM_H_
+
+#ifndef __KERNEL__
+#include "iostream.h"
+
+/** Data associated with a fd stream. */
+typedef struct FDData {
+    /** The socket file descriptor. */
+    int fd;
+} FDData;
+
+extern IOStream *fd_stream_new(int fd);
+extern int fd_stream_data(IOStream *io, FDData **data);
+extern int fd_stream_check(IOStream *io);
+
+#endif
+#endif /* !_XMC_FD_STREAM_H_ */
diff --git a/tools/vnet/libxutil/file_stream.c b/tools/vnet/libxutil/file_stream.c
new file mode 100644 (file)
index 0000000..7adbac0
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/** @file
+ * An IOStream implementation using FILE*.
+ */
+#ifndef __KERNEL__
+#include <stdio.h>
+#include <stdlib.h>
+#include "allocate.h"
+#include "file_stream.h"
+
+static int file_read(IOStream *s, void *buf, size_t n);
+static int file_write(IOStream *s, const void *buf, size_t n);
+static int file_error(IOStream *s);
+static int file_close(IOStream *s);
+static void file_free(IOStream *s);
+static int file_flush(IOStream *s);
+
+/** Methods used by a FILE* IOStream. */
+static const IOMethods file_methods = {
+    read:  file_read,
+    write: file_write,
+    error: file_error,
+    close: file_close,
+    free:  file_free,
+    flush: file_flush,
+};
+
+/** IOStream for stdin. */
+static IOStream _iostdin = {
+    methods: &file_methods,
+    data: (void*)1,
+    nofree: 1,
+};
+
+/** IOStream for stdout. */
+static IOStream _iostdout = {
+    methods: &file_methods,
+    data: (void*)2,
+    nofree: 1,
+};
+
+/** IOStream for stderr. */
+static IOStream _iostderr = {
+    methods: &file_methods,
+    data: (void*)3,
+    nofree: 1,
+};
+
+/** IOStream for stdin. */
+IOStream *iostdin = &_iostdin;
+
+/** IOStream for stdout. */
+IOStream *iostdout = &_iostdout;
+
+/** IOStream for stderr. */
+IOStream *iostderr = &_iostderr;
+
+/* Get the underlying FILE*.
+ *
+ * @param s file stream
+ * @return the stream s wraps
+ */
+static inline FILE *get_file(IOStream *s){
+     FILE *data = NULL;
+     switch((long)s->data){
+     case 1:
+         data = stdin;
+         break;
+     case 2:
+         data = stdout;
+         break;
+     case 3:
+         data = stderr;
+         break;
+     default:
+         data = (FILE*)s->data;
+         break;
+     }
+     return data;
+}
+
+/** Control buffering on the underlying stream, like setvbuf().
+ *
+ * @param io file stream
+ * @param buf buffer
+ * @param mode buffering mode (see man setvbuf())
+ * @param size buffer size
+ * @return 0 on success, non-zero otherwise
+ */
+int file_stream_setvbuf(IOStream *io, char *buf, int mode, size_t size){
+    return setvbuf(get_file(io), buf, mode, size);
+}
+
+/** Write to the underlying stream using fwrite();
+ *
+ * @param stream input
+ * @param buf where to put input
+ * @param n number of bytes to write
+ * @return number of bytes written
+ */
+static int file_write(IOStream *s, const void *buf, size_t n){
+    return fwrite(buf, 1, n, get_file(s));
+}
+
+/** Read from the underlying stream using fread();
+ *
+ * @param stream input
+ * @param buf where to put input
+ * @param n number of bytes to read
+ * @return number of bytes read
+ */
+static int file_read(IOStream *s, void *buf, size_t n){
+    return fread(buf, 1, n, get_file(s));
+}
+
+/** Fush the underlying stream using fflush().
+ *
+ * @param s file stream
+ * @return 0 on success, error code otherwise
+ */
+static int file_flush(IOStream *s){
+    return fflush(get_file(s));
+}
+
+/** Check if a stream has an error.
+ *
+ * @param s file stream
+ * @return 1 if has an error, 0 otherwise
+ */
+static int file_error(IOStream *s){
+    return ferror(get_file(s));
+}
+
+/** Close a file stream.
+ *
+ * @param s file stream to close
+ * @return result of the close
+ */
+static int file_close(IOStream *s){
+    int result = 0;
+    result = fclose(get_file(s));
+    return result;
+}
+
+/** Free a file stream.
+ *
+ * @param s file stream
+ */
+static void file_free(IOStream *s){
+    // Nothing extra to do - close did it all.
+}
+
+/** Create an IOStream for a stream.
+ *
+ * @param f stream to wrap
+ * @return new IOStream using f for i/o
+ */
+IOStream *file_stream_new(FILE *f){
+    IOStream *io = ALLOCATE(IOStream);
+    if(io){
+        io->methods = &file_methods;
+        io->data = (void*)f;
+    }
+    return io;
+}
+
+/** IOStream version of fopen().
+ *
+ * @param file name of the file to open
+ * @param flags giving the mode to open in (as for fopen())
+ * @return new stream for the open file, or 0 if failed
+ */
+IOStream *file_stream_fopen(const char *file, const char *flags){
+    IOStream *io = 0;
+    FILE *fin = fopen(file, flags);
+    if(fin){
+        io = file_stream_new(fin);
+        if(!io){
+            fclose(fin);
+        }
+    }
+    return io;
+}
+
+/** IOStream version of fdopen().
+ *
+ * @param fd file descriptor
+ * @param flags giving the mode to open in (as for fdopen())
+ * @return new stream for the open file, or 0 if failed.  Always takes
+ *         ownership of fd.
+ */
+IOStream *file_stream_fdopen(int fd, const char *flags){
+    IOStream *io = 0;
+    FILE *fin = fdopen(fd, flags);
+    if(fin){
+        io = file_stream_new(fin);
+        if(!io){
+            fclose(fin);
+        }
+    }
+    return io;
+}
+#endif
diff --git a/tools/vnet/libxutil/file_stream.h b/tools/vnet/libxutil/file_stream.h
new file mode 100644 (file)
index 0000000..f717656
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _XUTIL_FILE_STREAM_H_
+#define _XUTIL_FILE_STREAM_H_
+
+#ifndef __KERNEL__
+#include "iostream.h"
+#include <stdio.h>
+
+extern IOStream *file_stream_new(FILE *f);
+extern IOStream *file_stream_fopen(const char *file, const char *flags);
+extern IOStream *file_stream_fdopen(int fd, const char *flags);
+extern IOStream get_stream_stdout(void);
+extern IOStream get_stream_stderr(void);
+extern IOStream get_stream_stdin(void);
+
+extern int file_stream_setvbuf(IOStream *io, char *buf, int mode, size_t size);
+#endif
+#endif /* !_XUTIL_FILE_STREAM_H_ */
diff --git a/tools/vnet/libxutil/gzip_stream.c b/tools/vnet/libxutil/gzip_stream.c
new file mode 100644 (file)
index 0000000..ea14b82
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2003 Hewlett-Packard Company.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/** @file
+ * An IOStream implementation using zlib gzFile to provide
+ * compression and decompression.
+ */
+#ifndef __KERNEL__
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "zlib.h"
+
+#include "allocate.h"
+#include "gzip_stream.h"
+
+static int gzip_read(IOStream *s, void *buf, size_t n);
+static int gzip_write(IOStream *s, const void *buf, size_t n);
+static int gzip_error(IOStream *s);
+static int gzip_close(IOStream *s);
+static void gzip_free(IOStream *s);
+static int gzip_flush(IOStream *s);
+
+/** Methods used by a gzFile* IOStream. */
+static const IOMethods gzip_methods = {
+    read:  gzip_read,
+    write: gzip_write,
+    error: gzip_error,
+    close: gzip_close,
+    free:  gzip_free,
+    flush: gzip_flush,
+};
+
+/** Get the underlying gzFile*.
+ * 
+ * @param s gzip stream
+ * @return the stream s wraps
+ */
+static inline gzFile get_gzfile(IOStream *s){
+    return (gzFile)s->data;
+}
+
+/** Write to the underlying stream.
+ *
+ * @param stream destination
+ * @param buf data
+ * @param n number of bytes to write
+ * @return number of bytes written
+ */
+static int gzip_write(IOStream *s, const void *buf, size_t n){
+    return gzwrite(get_gzfile(s), (void*)buf, n);
+}
+
+/** Read from the underlying stream.
+ *
+ * @param stream input
+ * @param buf where to put input
+ * @param n number of bytes to read
+ * @return number of bytes read
+ */
+static int gzip_read(IOStream *s, void *buf, size_t n){
+    return gzread(get_gzfile(s), buf, n);
+}
+
+/** Flush the underlying stream.
+ *
+ * @param s gzip stream
+ * @return 0 on success, error code otherwise
+ */
+static int gzip_flush(IOStream *s){
+    //return gzflush(get_gzfile(s), Z_NO_FLUSH);
+    return gzflush(get_gzfile(s), Z_SYNC_FLUSH);
+    //return gzflush(get_gzfile(s), Z_FULL_FLUSH);
+}
+
+/** Check if a stream has an error.
+ *
+ * @param s gzip stream
+ * @return 1 if has an error, 0 otherwise
+ */
+static int gzip_error(IOStream *s){
+    int err;
+    gzFile *gz = get_gzfile(s);
+    gzerror(gz, &err);
+    return (err == Z_ERRNO ? 1 /* ferror(gzfile(gz)) */ : err);
+}
+
+/** Close a gzip stream.
+ *
+ * @param s gzip stream to close
+ * @return result of the close
+ */
+static int gzip_close(IOStream *s){
+    int result = 0;
+    result = gzclose(get_gzfile(s));
+    return result;
+}
+
+/** Free a gzip stream.
+ *
+ * @param s gzip stream
+ */
+static void gzip_free(IOStream *s){
+    // Nothing to do - close did it all.
+}
+
+/** Create an IOStream for a gzip stream.
+ *
+ * @param f stream to wrap
+ * @return new IOStream using f for i/o
+ */
+IOStream *gzip_stream_new(gzFile *f){
+    IOStream *io = ALLOCATE(IOStream);
+    if(io){
+        io->methods = &gzip_methods;
+        io->data = (void*)f;
+    }
+    return io;
+}
+
+/** IOStream version of fopen().
+ *
+ * @param file name of the file to open
+ * @param flags giving the mode to open in (as for fopen())
+ * @return new stream for the open file, or NULL if failed
+ */
+IOStream *gzip_stream_fopen(const char *file, const char *flags){
+    IOStream *io = NULL;
+    gzFile *fgz;
+    fgz = gzopen(file, flags);
+    if(fgz){
+        io = gzip_stream_new(fgz);
+        if(!io){
+            gzclose(fgz);
+        }
+    }
+    return io;
+}
+
+/** IOStream version of fdopen().
+ *
+ * @param fd file descriptor
+ * @param flags giving the mode to open in (as for fdopen())
+ * @return new stream for the open file, or NULL if failed.  Always takes
+ *         ownership of fd.
+ */
+IOStream *gzip_stream_fdopen(int fd, const char *flags){
+    IOStream *io = NULL;
+    gzFile *fgz;
+    fgz = gzdopen(fd, flags);
+    if(fgz){
+        io = gzip_stream_new(fgz);
+        if(!io)
+            gzclose(fgz);
+    }
+    return io;
+}
+#endif
diff --git a/tools/vnet/libxutil/gzip_stream.h b/tools/vnet/libxutil/gzip_stream.h
new file mode 100644 (file)
index 0000000..fd28e39
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2003 Hewlett-Packard Company.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _XUTIL_GZIP_STREAM_H_
+#define _XUTIL_GZIP_STREAM_H_
+
+#ifndef __KERNEL__
+#include "iostream.h"
+#include "zlib.h"
+
+extern IOStream *gzip_stream_new(gzFile *f);
+extern IOStream *gzip_stream_fopen(const char *file, const char *flags);
+extern IOStream *gzip_stream_fdopen(int fd, const char *flags);
+#endif
+#endif /* !_XUTIL_GZIP_STREAM_H_ */
diff --git a/tools/vnet/libxutil/hash_table.c b/tools/vnet/libxutil/hash_table.c
new file mode 100644 (file)
index 0000000..13da946
--- /dev/null
@@ -0,0 +1,640 @@
+/*
+ * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef __KERNEL__
+#  include <linux/config.h>
+#  include <linux/module.h>
+#  include <linux/kernel.h>
+#  include <linux/errno.h>
+#else
+#  include <errno.h>
+#  include <stddef.h>
+#endif
+
+//#include <limits.h>
+
+#include "allocate.h"
+#include "hash_table.h"
+
+/** @file
+ * Base support for hashtables.
+ *
+ * Hash codes are reduced modulo the number of buckets to index tables,
+ * so there is no need for hash functions to limit the range of hashcodes.
+ * In fact it is assumed that hashcodes do not change when the number of
+ * buckets in the table changes.
+ */
+
+/*==========================================================================*/
+/** Number of bits in half a word. */
+//#if __WORDSIZE == 64
+//#define HALF_WORD_BITS 32
+//#else
+#define HALF_WORD_BITS 16
+//#endif
+
+/** Mask for lo half of a word. On 32-bit this is 
+ * (1<<16) - 1 = 65535 = 0xffff
+ * It's 4294967295 = 0xffffffff on 64-bit.
+ */
+#define LO_HALF_MASK ((1 << HALF_WORD_BITS) - 1)
+
+/** Get the lo half of a word. */
+#define LO_HALF(x) ((x) & LO_HALF_MASK)
+
+/** Get the hi half of a word. */
+#define HI_HALF(x) ((x) >> HALF_WORD_BITS)
+
+/** Do a full hash on both inputs, using DES-style non-linear scrambling.
+ * Both inputs are replaced with the results of the hash.
+ *
+ * @param pleft input/output word
+ * @param pright input/output word
+ */
+void pseudo_des(unsigned long *pleft, unsigned long *pright){
+    // Bit-rich mixing constant.
+    static const unsigned long a_mixer[] = {
+        0xbaa96887L, 0x1e17d32cL, 0x03bcdc3cL, 0x0f33d1b2L, };
+
+    // Bit-rich mixing constant.
+    static const unsigned long b_mixer[] = {
+        0x4b0f3b58L, 0xe874f0c3L, 0x6955c5a6L, 0x55a7ca46L, };
+
+    // Number of iterations - must be 2 or 4.
+    static const int ncycle = 4;
+    //static const int ncycle = 2;
+
+    unsigned long left = *pleft, right = *pright;
+    unsigned long v, v_hi, v_lo;
+    int i;
+
+    for(i=0; i<ncycle; i++){
+        // Flip some bits in right to get v.
+        v = right;
+        v ^= a_mixer[i];
+        // Get lo and hi halves of v.
+        v_lo = LO_HALF(v);
+        v_hi = HI_HALF(v);
+        // Non-linear mix of the halves of v.
+        v = ((v_lo * v_lo) + ~(v_hi * v_hi));
+        // Swap the halves of v.
+        v = (HI_HALF(v) | (LO_HALF(v) << HALF_WORD_BITS));
+        // Flip some bits.
+        v ^= b_mixer[i];
+        // More non-linear mixing.
+        v += (v_lo * v_hi);
+        v ^= left;
+        left = right;
+        right = v;
+    }
+    *pleft = left;
+    *pright = right;
+}
+
+/** Hash a string.
+ *
+ * @param s input to hash
+ * @return hashcode
+ */
+Hashcode hash_string(char *s){
+    Hashcode h = 0;
+    if(s){
+        for( ; *s; s++){
+            h = hash_2ul(h, *s);
+        }
+    }
+    return h;
+}
+
+/** Get the bucket for a hashcode in a hash table.
+ *
+ * @param table to get bucket from
+ * @param hashcode to get bucket for
+ * @return bucket
+ */
+inline HTBucket * get_bucket(HashTable *table, Hashcode hashcode){
+    return table->buckets + (hashcode % table->buckets_n);
+}
+
+/** Initialize a hash table.
+ * Can be safely called more than once.
+ *
+ * @param table to initialize
+ */
+void HashTable_init(HashTable *table){
+    int i;
+
+    if(!table->init_done){
+        table->init_done = 1;
+        table->next_id = 0;
+        for(i=0; i<table->buckets_n; i++){
+            HTBucket *bucket = get_bucket(table, i);
+            bucket->head = 0;
+            bucket->count = 0;
+        }
+        table->entry_count = 0;
+    }
+}
+
+/** Allocate a new hashtable.
+ * If the number of buckets is not positive the default is used.
+ * The number of buckets should usually be prime.
+ *
+ * @param buckets_n number of buckets
+ * @return new hashtable or null
+ */
+HashTable *HashTable_new(int buckets_n){
+    HashTable *z = ALLOCATE(HashTable);
+    if(!z) goto exit;
+    if(buckets_n <= 0){
+        buckets_n = HT_BUCKETS_N;
+    }
+    z->buckets = (HTBucket*)allocate(buckets_n * sizeof(HTBucket));
+    if(!z->buckets){
+        deallocate(z);
+        z = 0;
+        goto exit;
+    }
+    z->buckets_n = buckets_n;
+    HashTable_init(z);
+  exit:
+    return z;
+}
+
+/** Free a hashtable.
+ * Any entries are removed and freed.
+ *
+ * @param h hashtable (ignored if null)
+ */
+void HashTable_free(HashTable *h){
+    if(h){
+        HashTable_clear(h);
+        deallocate(h->buckets);
+        deallocate(h);
+    }
+}
+
+/** Push an entry on the list in the bucket for a given hashcode.
+ *
+ * @param table to add entry to
+ * @param hashcode for the entry
+ * @param entry to add
+ */
+static inline void push_on_bucket(HashTable *table, Hashcode hashcode,
+                                 HTEntry *entry){
+    HTBucket *bucket;
+    HTEntry *old_head;
+
+    bucket = get_bucket(table, hashcode);
+    old_head = bucket->head;
+    bucket->count++;
+    bucket->head = entry;
+    entry->next = old_head;
+}
+
+/** Change the number of buckets in a hashtable.
+ * No-op if the number of buckets is not positive.
+ * Existing entries are reallocated to buckets based on their hashcodes.
+ * The table is unmodified if the number of buckets cannot be changed.
+ *
+ * @param table hashtable
+ * @param buckets_n new number of buckets
+ * @return 0 on success, error code otherwise
+ */
+int HashTable_set_buckets_n(HashTable *table, int buckets_n){
+    int err = 0;
+    HTBucket *old_buckets = table->buckets;
+    int old_buckets_n = table->buckets_n;
+    int i;
+
+    if(buckets_n <= 0){
+        err = -EINVAL;
+        goto exit;
+    }
+    table->buckets = (HTBucket*)allocate(buckets_n * sizeof(HTBucket));
+    if(!table->buckets){
+        err = -ENOMEM;
+        table->buckets = old_buckets;
+        goto exit;
+    }
+    table->buckets_n = buckets_n;
+    for(i=0; i<old_buckets_n; i++){
+        HTBucket *bucket = old_buckets + i;
+        HTEntry *entry, *next;
+        for(entry = bucket->head; entry; entry = next){
+            next = entry->next;
+            push_on_bucket(table, entry->hashcode, entry);
+        }
+    }
+    deallocate(old_buckets);
+  exit:
+    return err;
+}
+
+/** Adjust the number of buckets so the table is neither too full nor too empty.
+ * The table is unmodified if adjusting fails.
+ *
+ * @param table hash table
+ * @param buckets_min minimum number of buckets (use default if 0 or negative)
+ * @return 0 on success, error code otherwise
+ */
+int HashTable_adjust(HashTable *table, int buckets_min){
+    int buckets_n = 0;
+    int err = 0;
+    if(buckets_min <= 0) buckets_min = HT_BUCKETS_N;
+    if(table->entry_count >= table->buckets_n){
+        // The table is dense - expand it.
+        buckets_n = 2 * table->buckets_n;
+    } else if((table->buckets_n > buckets_min) &&
+              (4 * table->entry_count < table->buckets_n)){
+        // The table is more than minimum size and sparse - shrink it.
+        buckets_n = 2 * table->entry_count;
+        if(buckets_n < buckets_min) buckets_n = buckets_min;
+    }
+    if(buckets_n){
+        err = HashTable_set_buckets_n(table, buckets_n);
+    }
+    return err;
+}
+
+/** Allocate a new entry for a given value.
+ *
+ * @param value to put in the entry
+ * @return entry, or 0 on failure
+ */
+HTEntry * HTEntry_new(Hashcode hashcode, void *key, void *value){
+    HTEntry *z = ALLOCATE(HTEntry);
+    if(z){
+        z->hashcode = hashcode;
+        z->key = key;
+        z->value = value;
+    }
+    return z;
+}
+
+/** Free an entry.
+ *
+ * @param z entry to free
+ */
+inline void HTEntry_free(HTEntry *z){
+    if(z){
+        deallocate(z);
+    }
+}
+
+/** Free an entry in a hashtable.
+ * The table's entry_free_fn is used is defined, otherwise 
+ * the HTEntry itself is freed.
+ *
+ * @param table hashtable
+ * @param entry to free
+ */
+inline void HashTable_free_entry(HashTable *table, HTEntry *entry){
+    if(!entry)return;
+    if(table && table->entry_free_fn){
+        table->entry_free_fn(table, entry);
+    } else {
+        HTEntry_free(entry);
+    }
+}
+
+/** Get the first entry satisfying a test from the bucket for the
+ * given hashcode.
+ *
+ * @param table to look in
+ * @param hashcode indicates the bucket
+ * @param test_fn test to apply to elements
+ * @param arg first argument to calls to test_fn
+ * @return entry found, or 0
+ */
+inline HTEntry * HashTable_find_entry(HashTable *table, Hashcode hashcode,
+                                     TableTestFn *test_fn, TableArg arg){
+    HTBucket *bucket;
+    HTEntry *entry = 0;
+    HTEntry *next;
+
+    bucket = get_bucket(table, hashcode);
+    for(entry = bucket->head; entry; entry = next){
+        next = entry->next;
+        if(test_fn(arg, table, entry)){
+            break;
+        }
+    }
+    return entry;
+}
+
+/** Test hashtable keys for equality.
+ * Uses the table's key_equal_fn if defined, otherwise pointer equality.
+ *
+ * @param key1 key to compare
+ * @param key2 key to compare
+ * @return 1 if equal, 0 otherwise
+ */
+inline int HashTable_key_equal(HashTable *table, void *key1, void *key2){
+    return (table->key_equal_fn ? table->key_equal_fn(key1, key2) : key1==key2);
+}
+
+/** Compute the hashcode of a hashtable key.
+ * The table's key_hash_fn is used if defined, otherwise the address of
+ * the key is hashed.
+ *
+ * @param table hashtable
+ * @param key to hash
+ * @return hashcode
+ */
+inline Hashcode HashTable_key_hash(HashTable *table, void *key){
+    return (table->key_hash_fn ? table->key_hash_fn(key) : hash_ul((unsigned long)key));
+}
+
+/** Test if an entry has a given key.
+ *
+ * @param arg containing key to test for
+ * @param table the entry is in
+ * @param entry to test
+ * @return 1 if the entry has the key, 0 otherwise
+ */
+static inline int has_key(TableArg arg, HashTable *table, HTEntry *entry){
+    return HashTable_key_equal(table, arg.ptr, entry->key);
+}
+
+/** Get an entry with a given key.
+ *
+ * @param table to search
+ * @param key to look for
+ * @return entry if found, null otherwise
+ */
+#if 0
+inline HTEntry * HashTable_get_entry(HashTable *table, void *key){
+    TableArg arg = { ptr: key };
+    return HashTable_find_entry(table, HashTable_key_hash(table, key), has_key, arg);
+}
+#else
+inline HTEntry * HashTable_get_entry(HashTable *table, void *key){
+    Hashcode hashcode;
+    HTBucket *bucket;
+    HTEntry *entry = 0;
+    HTEntry *next;
+
+    hashcode = HashTable_key_hash(table, key);
+    bucket = get_bucket(table, hashcode);
+    for(entry = bucket->head; entry; entry = next){
+        next = entry->next;
+        if(HashTable_key_equal(table, key, entry->key)){
+            break;
+        }
+    }
+    return entry;
+}
+#endif
+
+/** Get the value of an entry with a given key.
+ *
+ * @param table to search
+ * @param key to look for
+ * @return value if an entry was found, null otherwise
+ */
+inline void * HashTable_get(HashTable *table, void *key){
+    HTEntry *entry = HashTable_get_entry(table, key);
+    return (entry ? entry->value : 0);
+}
+
+/** Print the buckets in a table.
+ *
+ * @param table to print
+ */
+void show_buckets(HashTable *table, IOStream *io){
+    int i,j ;
+    IOStream_print(io, "entry_count=%d buckets_n=%d\n", table->entry_count, table->buckets_n);
+    for(i=0; i<table->buckets_n; i++){
+        if(0 || table->buckets[i].count>0){
+            IOStream_print(io, "bucket %3d %3d %10p ", i,
+                        table->buckets[i].count,
+                        table->buckets[i].head);
+            for(j = table->buckets[i].count; j>0; j--){
+                IOStream_print(io, "+");
+            }
+            IOStream_print(io, "\n");
+        }
+    }
+    HashTable_print(table, io); 
+}
+    
+/** Print an entry in a table.
+ *
+ * @param entry to print
+ * @param arg a pointer to an IOStream to print to
+ * @return 0
+ */
+static int print_entry(TableArg arg, HashTable *table, HTEntry *entry){
+    IOStream *io = (IOStream*)arg.ptr;
+    IOStream_print(io, " b=%4lx h=%08lx i=%08lx |-> e=%8p k=%8p v=%8p\n",
+                entry->hashcode % table->buckets_n,
+                entry->hashcode,
+                entry->index,
+                entry, entry->key, entry->value);
+    return 0;
+}
+
+/** Print a hash table.
+ *
+ * @param table to print
+ */
+void HashTable_print(HashTable *table, IOStream *io){
+    IOStream_print(io, "{\n");
+    HashTable_map(table, print_entry, (TableArg){ ptr: io });
+    IOStream_print(io, "}\n");
+}
+/*==========================================================================*/
+
+/** Get the next entry id to use for a table.
+ *
+ * @param table hash table
+ * @return non-zero entry id
+ */
+static inline unsigned long get_next_id(HashTable *table){
+    unsigned long id;
+
+    if(table->next_id == 0){
+        table->next_id = 1;
+    }
+    id = table->next_id++;
+    return id;
+}
+
+/** Add an entry to the bucket for the
+ * given hashcode.
+ *
+ * @param table to insert in
+ * @param hashcode indicates the bucket
+ * @param key to add an entry for
+ * @param value to add an entry for
+ * @return entry on success, 0 on failure
+ */
+inline HTEntry * HashTable_add_entry(HashTable *table, Hashcode hashcode, void *key, void *value){
+    HTEntry *entry = HTEntry_new(hashcode, key, value);
+    if(entry){
+        entry->index = get_next_id(table);
+        push_on_bucket(table, hashcode, entry);
+        table->entry_count++;
+    }
+    return entry;
+}
+
+/** Move the front entry for a bucket to the correct point in the bucket order as
+ * defined by the order function. If this is called every time a new entry is added
+ * the bucket will be maintained in sorted order.
+ *
+ * @param table to modify
+ * @param hashcode indicates the bucket
+ * @param order entry comparison function
+ * @return 0 if an entry was moved, 1 if not
+ */
+int HashTable_order_bucket(HashTable *table, Hashcode hashcode, TableOrderFn *order){
+    HTEntry *new_entry = NULL, *prev = NULL, *entry = NULL;
+    HTBucket *bucket;
+    int err = 1;
+
+    bucket = get_bucket(table, hashcode);
+    new_entry = bucket->head;
+    if(!new_entry || !new_entry->next) goto exit;
+    for(entry = new_entry->next; entry; prev = entry, entry = entry->next){
+        if(order(new_entry, entry) <= 0) break;
+    }
+    if(prev){
+        err = 0;
+        bucket->head = new_entry->next; 
+        new_entry->next = entry;
+        prev->next = new_entry;
+    }
+  exit:
+    return err;
+}
+
+/** Add an entry to a hashtable.
+ * The entry is added to the bucket for its key's hashcode.
+ *
+ * @param table to insert in
+ * @param key to add an entry for
+ * @param value to add an entry for
+ * @return entry on success, 0 on failure
+ */
+inline HTEntry * HashTable_add(HashTable *table, void *key, void *value){
+    return HashTable_add_entry(table, HashTable_key_hash(table, key), key, value);
+}
+
+
+/** Remove entries satisfying a test from the bucket for the
+ * given hashcode. 
+ *
+ * @param table to remove from
+ * @param hashcode indicates the bucket
+ * @param test_fn test to apply to elements
+ * @param arg first argument to calls to test_fn
+ * @return number of entries removed
+ */
+inline int HashTable_remove_entry(HashTable *table, Hashcode hashcode,
+                                 TableTestFn *test_fn, TableArg arg){
+    HTBucket *bucket;
+    HTEntry *entry, *prev = 0, *next;
+    int removed_count = 0;
+
+    bucket = get_bucket(table, hashcode);
+    for(entry = bucket->head; entry; entry = next){
+        next = entry->next;
+        if(test_fn(arg, table, entry)){
+            if(prev){
+                prev->next = next;
+            } else {
+                bucket->head = next;
+            }
+            bucket->count--;
+            table->entry_count--;
+            removed_count++;
+            HashTable_free_entry(table, entry);
+            entry = 0;
+        }
+        prev = entry;
+    }
+    return removed_count;
+}
+
+/** Remove entries with a given key. 
+ *
+ * @param table to remove from
+ * @param key of entries to remove
+ * @return number of entries removed
+ */
+inline int HashTable_remove(HashTable *table, void *key){
+#if 1
+    Hashcode hashcode;
+    HTBucket *bucket;
+    HTEntry *entry, *prev = 0, *next;
+    int removed_count = 0;
+
+    hashcode = HashTable_key_hash(table, key);
+    bucket = get_bucket(table, hashcode);
+    for(entry = bucket->head; entry; entry = next){
+        next = entry->next;
+        if(HashTable_key_equal(table, key, entry->key)){
+            if(prev){
+                prev->next = next;
+            } else {
+                bucket->head = next;
+            }
+            bucket->count--;
+            table->entry_count--;
+            removed_count++;
+            HashTable_free_entry(table, entry);
+            entry = 0;
+        }
+        prev = entry;
+    }
+    return removed_count;
+#else
+    return HashTable_remove_entry(table, HashTable_key_hash(table, key),
+                                 has_key, (TableArg){ ptr: key});
+#endif
+}
+
+/** Remove (and free) all the entries in a bucket.
+ *
+ * @param bucket to clear
+ */
+static inline void bucket_clear(HashTable *table, HTBucket *bucket){
+    HTEntry *entry, *next;
+
+    for(entry = bucket->head; entry; entry = next){
+        next = entry->next;
+        HashTable_free_entry(table, entry);
+    }
+    bucket->head = 0;
+    table->entry_count -= bucket->count;
+    bucket->count = 0;
+}
+
+/** Remove (and free) all the entries in a table.
+ *
+ * @param table to clear
+ */
+void HashTable_clear(HashTable *table){
+    int i, n = table->buckets_n;
+
+    for(i=0; i<n; i++){
+        bucket_clear(table, table->buckets + i);
+    }
+}
diff --git a/tools/vnet/libxutil/hash_table.h b/tools/vnet/libxutil/hash_table.h
new file mode 100644 (file)
index 0000000..6608b49
--- /dev/null
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _XUTIL_HASH_TABLE_H_
+#define _XUTIL_HASH_TABLE_H_
+
+#include "iostream.h"
+
+typedef unsigned long Hashcode;
+
+/** Type used to pass parameters to table functions. */
+typedef union TableArg {
+    unsigned long ul;
+    void *ptr;
+} TableArg;
+
+/** An entry in a bucket list. */
+typedef struct HTEntry {
+    /** Hashcode of the entry's key. */
+    Hashcode hashcode;
+    /** Identifier for this entry in the table. */
+    int index;
+    /** The key for this entry. */
+    void *key;
+    /** The value in this entry. */
+    void *value;
+    /** The next entry in the list. */
+    struct HTEntry *next;
+} HTEntry;
+
+/** A bucket in a rule table. */
+typedef struct HTBucket {
+    /** Number of entries in the bucket. */
+    int count;
+    /** First entry in the bucket (may be null). */
+    HTEntry *head;
+} HTBucket;
+
+/** Default number of buckets in a hash table.
+ * You want enough buckets so the lists in the buckets will typically be short.
+ * It's a good idea if this is prime, since that will help to spread hashcodes
+ * around the table.
+ */
+//#define HT_BUCKETS_N 1
+//#define HT_BUCKETS_N 3
+//#define HT_BUCKETS_N 7
+//#define HT_BUCKETS_N 17
+//#define HT_BUCKETS_N 97
+//#define HT_BUCKETS_N 211
+//#define HT_BUCKETS_N 401
+#define HT_BUCKETS_N 1021
+
+typedef struct HashTable HashTable;
+
+/** Type for a function used to select table entries. */
+typedef int TableTestFn(TableArg arg, HashTable *table, HTEntry *entry);
+
+/** Type for a function to map over table entries. */
+typedef int TableMapFn(TableArg arg, HashTable *table, HTEntry *entry);
+
+/** Type for a function to free table entries. */
+typedef void TableFreeFn(HashTable *table, HTEntry *entry);
+
+/** Type for a function to hash table keys. */
+typedef Hashcode TableHashFn(void *key);
+
+/** Type for a function to test table keys for equality. */
+typedef int TableEqualFn(void *key1, void *key2);
+
+/** Type for a function to order table entries. */
+typedef int TableOrderFn(HTEntry *e1, HTEntry *e2);
+
+/** General hash table.
+ * A hash table with a list in each bucket.
+ * Functions can be supplied for freeing entries, hashing keys, and comparing keys.
+ * These all default to 0, when default behaviour treating keys as integers is used.
+ */
+struct HashTable {
+    /** Flag indicating whether the table has been initialised. */
+    int init_done;
+    /** Next value for the id field in inserted rules. */
+    unsigned long next_id;
+    /** Number of buckets in the bucket array. */
+    int buckets_n;
+    /** Array of buckets, each with its own list. */
+    HTBucket *buckets;
+    /** Number of entries in the table. */
+    int entry_count;
+    /** Function to free keys and values in entries. */
+    TableFreeFn *entry_free_fn;
+    /** Function to hash keys. */
+    TableHashFn *key_hash_fn;
+    /** Function to compare keys for equality. */
+    TableEqualFn *key_equal_fn;
+    /** Place for the user of the table to hang extra data. */
+    void *user_data;
+};
+
+extern HashTable *HashTable_new(int bucket_n);
+extern void HashTable_free(HashTable *table);
+extern HTEntry * HTEntry_new(Hashcode hashcode, void *key, void *value);
+extern void HTEntry_free(HTEntry *entry);
+extern int HashTable_set_bucket_n(HashTable *table, int bucket_n);
+extern void HashTable_clear(HashTable *table);
+extern HTEntry * HashTable_add_entry(HashTable *table, Hashcode hashcode, void *key, void *value);
+extern HTEntry * HashTable_get_entry(HashTable *table, void *key);
+extern HTEntry * HashTable_add(HashTable *table, void *key, void *value);
+extern void * HashTable_get(HashTable *table, void *key);
+extern int HashTable_remove(HashTable *table, void *key);
+extern HTEntry * HashTable_find_entry(HashTable *table, Hashcode hashcode,
+                                      TableTestFn *test_fn, TableArg arg);
+extern int HashTable_remove_entry(HashTable *table, Hashcode hashcode,
+                                   TableTestFn *test_fn, TableArg arg);
+//extern int HashTable_map(HashTable *table, TableMapFn *map_fn, TableArg arg);
+extern void HashTable_print(HashTable *table, IOStream *out);
+extern int HashTable_set_buckets_n(HashTable *table, int buckets_n);
+extern int HashTable_adjust(HashTable *table, int buckets_min);
+extern void pseudo_des(unsigned long *pleft, unsigned long *pright);
+extern Hashcode hash_string(char *s);
+
+extern int HashTable_order_bucket(HashTable *table, Hashcode hashcode, TableOrderFn *order);
+
+/** Control whether to use hashing based on DES or simple
+ * hashing. DES hashing is `more random' but much more expensive.
+ */
+#define HASH_PSEUDO_DES 0
+
+/** Hash a long using a quick and dirty linear congruential random number generator.
+ *  See `Numerical Recipes in C', Chapter 7, "An Even Quicker Generator".
+ *
+ * @param a value to hash
+ * @return hashed input
+ */
+static inline unsigned long lcrng_hash(unsigned long a){
+    return (1664525L * a + 1013904223L);
+}
+
+/** Hash an unsigned long.
+ *
+ * @param a input to hash
+ * @return hashcode
+ */
+static inline Hashcode hash_ul(unsigned long a){
+#if HASH_PSEUDO_DES
+    unsigned long left = a;
+    unsigned long right = 0L;
+    pseudo_des(&left, &right);
+    return right;
+#else
+    a = lcrng_hash(a);
+    a = lcrng_hash(a);
+    return a;
+#endif
+}
+
+/** Hash two unsigned longs together.
+ *
+ * @param a input to hash
+ * @param b input to hash
+ * @return hashcode
+ */
+static inline Hashcode hash_2ul(unsigned long a, unsigned long b){
+#if HASH_PSEUDO_DES
+    unsigned long left = a;
+    unsigned long right = b;
+    pseudo_des(&left, &right);
+    return right;
+#else
+    a = lcrng_hash(a);
+    a ^= b;
+    a = lcrng_hash(a);
+    return a;
+#endif
+}
+
+/** Hash a hashcode and an unsigned long together.
+ *
+ * @param a input hashcode
+ * @param b input to hash
+ * @return hashcode
+ */
+static inline Hashcode hash_hul(Hashcode a, unsigned long b){
+#if HASH_PSEUDO_DES
+    unsigned long left = a;
+    unsigned long right = b;
+    pseudo_des(&left, &right);
+    return right;
+#else
+    a ^= b;
+    a = lcrng_hash(a);
+    return a;
+#endif
+}
+
+/** Macro to declare variables for HashTable_for_each() to use.
+ *
+ * @param entry variable that is set to entries in the table
+ */
+#define HashTable_for_decl(entry) \
+  HashTable *_var_table; \
+  HTBucket *_var_bucket; \
+  HTBucket *_var_end; \
+  HTEntry *_var_next; \
+  HTEntry *entry
+
+/** Macro to iterate over the entries in a hashtable.
+ * Must be in a scope where HashTable_for_decl() has been used to declare
+ * variables for it to use.
+ * The variable 'entry' is iterated over entries in the table.
+ * The code produced is syntactically a loop, so it must be followed by
+ * a loop body, typically some statements in braces:
+ * HashTable_for_each(entry, table){ ...loop body... }
+ *
+ * HashTable_for_each() and HashTable_for_decl() cannot be used for nested
+ * loops as variables will clash.
+ *
+ * @note The simplest way to code a direct loop over the entries in a hashtable
+ * is to use a loop over the buckets, with a nested loop over the entries
+ * in a bucket. Using this approach in a macro means the macro contains
+ * an opening brace, and calls to it must be followed by 2 braces!
+ * To avoid this the code has been restructured so that it is a for loop.
+ * So that statements could be used in the test expression of the for loop,
+ * we have used the gcc statement expression extension ({ ... }).
+ *
+ * @param entry variable to iterate over the entries
+ * @param table to iterate over (non-null)
+ */
+#define HashTable_for_each(entry, table) \
+  _var_table = table; \
+  _var_bucket = _var_table->buckets; \
+  _var_end = _var_bucket + _var_table->buckets_n; \
+  for(entry=0, _var_next=0; \
+      ({ if(_var_next){ \
+             entry = _var_next; \
+             _var_next = entry->next; \
+          } else { \
+             while(_var_bucket < _var_end){ \
+                 entry = _var_bucket->head; \
+                 _var_bucket++; \
+                 if(entry){ \
+                      _var_next = entry->next; \
+                      break; \
+                 } \
+             } \
+          }; \
+         entry; }); \
+      entry = _var_next )
+
+/** Map a function over the entries in a table.
+ * Mapping stops when the function returns a non-zero value.
+ * Uses the gcc statement expression extension ({ ... }).
+ *
+ * @param table to map over
+ * @param fn function to apply to entries
+ * @param arg first argument to call the function with
+ * @return 0 if fn always returned 0, first non-zero value otherwise
+ */
+#define HashTable_map(table, fn, arg) \
+  ({ HashTable_for_decl(_var_entry); \
+    TableArg _var_arg = arg; \
+    int _var_value = 0; \
+    HashTable_for_each(_var_entry, table){ \
+        if((_var_value = fn(_var_arg, _var_table, _var_entry))) break; \
+    } \
+    _var_value; })
+
+/** Cast x to the type for a key or value in a hash table.
+ * This avoids compiler warnings when using short integers
+ * as keys or values (especially on 64-bit platforms).
+ */
+#define HKEY(x) ((void*)(unsigned long)(x))
+
+/** Cast x from the type for a key or value in a hash table.
+ * to an unsigned long. This avoids compiler warnings when using
+ * short integers as keys or values (especially on 64-bit platforms).
+ */
+#define HVAL(x) ((unsigned long)(x))
+
+#endif /* !_XUTIL_HASH_TABLE_H_ */
diff --git a/tools/vnet/libxutil/iostream.c b/tools/vnet/libxutil/iostream.c
new file mode 100644 (file)
index 0000000..39a6217
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "iostream.h"
+#include "sys_string.h"
+
+/** Print on a stream, like vfprintf().
+ *
+ * @param stream to print to
+ * @param format for the print (as fprintf())
+ * @param args arguments to print
+ * @return result code from the print
+ */
+int IOStream_vprint(IOStream *stream, const char *format, va_list args){
+  char buffer[1024];
+  int k = sizeof(buffer), n;
+
+  n = vsnprintf(buffer, k, (char*)format, args);
+  if(n < 0 || n > k ){
+      n = k;
+  }
+  n = IOStream_write(stream, buffer, n);
+  return n;
+}
+
+/** Print on a stream, like fprintf().
+ *
+ * @param stream to print to
+ * @param format for the print (as fprintf())
+ * @return result code from the print
+ */
+int IOStream_print(IOStream *stream, const char *format, ...){
+  va_list args;
+  int result = -1;
+
+  va_start(args, format);
+  result = IOStream_vprint(stream, format, args);
+  va_end(args);
+  return result;
+}
diff --git a/tools/vnet/libxutil/iostream.h b/tools/vnet/libxutil/iostream.h
new file mode 100644 (file)
index 0000000..f41ca56
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _XUTIL_IOSTREAM_H_
+#define _XUTIL_IOSTREAM_H_
+
+#include <stdarg.h>
+
+#ifdef __KERNEL__
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#else
+#include <errno.h>
+#include <stdint.h>
+#include <stddef.h>
+#endif
+
+#include "allocate.h"
+
+/** End of input return value (for getc). */
+#define IOSTREAM_EOF -1
+
+/** An input/output abstraction.
+ */
+typedef struct IOStream IOStream;
+
+/** Record of the functions to use for operations on an
+ * IOStream implementation.
+ */
+typedef struct IOMethods {
+    /** Read function.  Called with the user data, buffer to read into
+     * and number of bytes to read.  Must return number of bytes read
+     * on success, less than zero on error.
+     */
+    int (*read)(IOStream *stream, void *buf, size_t n);
+
+    /** Write function. Called with user data, buffer to write and
+     * number of bytes to write. Must return number of bytes written on
+     * success, less than zero otherwise.
+     */
+    int (*write)(IOStream *stream, const void *buf, size_t n);
+
+    int (*flush)(IOStream *s);
+
+    int (*error)(IOStream *s);
+
+    int (*close)(IOStream *s);
+
+    void (*free)(IOStream *s);
+
+    void (*lock)(IOStream *s);
+    void (*unlock)(IOStream *s);
+
+} IOMethods;
+
+/** Abstract i/o object.
+ */
+struct IOStream {
+    /** Methods to use to implement operations. */
+    const IOMethods *methods;
+    /** Private state for the implementation. */
+    const void *data;
+    /** Flag indicating whether the stream is closed. */
+    int closed;
+    /** Number of bytes written. */
+    int written;
+    /** Number of bytes read. */
+    int read;
+    /** Flag indicating whether not to free when closed. */
+    int nofree;
+};
+
+
+/** IOStream version of stdin. */
+extern IOStream *iostdin;
+
+/** IOStream version of stdout, */
+extern IOStream *iostdout;
+
+/** IOStream version of stderr. */
+extern IOStream *iostderr;
+
+extern int IOStream_print(IOStream *io, const char *format, ...);
+extern int IOStream_vprint(IOStream *io, const char *format, va_list args);
+
+/** Read from a stream.
+ *
+ * @param stream input
+ * @param buf where to put input
+ * @param n number of bytes to read
+ * @return if ok, number of bytes read, otherwise negative error code
+ */
+static inline int IOStream_read(IOStream *stream, void *buf, size_t n){
+    int result;
+    if(stream->closed){
+        result = -EIO;
+        goto exit;
+    }
+    if(!stream->methods || !stream->methods->read){
+        result = -EINVAL;
+        goto exit;
+    }
+    result = (stream->methods->read)(stream, buf, n);
+    if(result > 0){
+        stream->read += result;
+    }
+  exit:
+    return result;
+}
+
+/** Write to a stream.
+ *
+ * @param stream input
+ * @param buf where to put input
+ * @param n number of bytes to write
+ * @return if ok, number of bytes written, otherwise negative error code
+ */
+static inline int IOStream_write(IOStream *stream, const void *buf, size_t n){
+    int result;
+    if(stream->closed){
+        result = -EIO;
+        goto exit;
+    }
+    if(!stream->methods || !stream->methods->write){
+        result = -EINVAL;
+        goto exit;
+    }
+    result = (stream->methods->write)(stream, buf, n);
+    if(result > 0){
+        stream->written += result;
+    }
+  exit:
+    return result;
+}
+
+/** Flush the stream.
+ *
+ * @param stream stream
+ * @return 0 on success, negative error code otherwise
+ */
+static inline int IOStream_flush(IOStream *stream){
+    int result = 0;
+    if(stream->closed){
+        result = -EIO;
+    } else if(stream->methods->flush){
+        result = (stream->methods->flush)(stream);
+    }
+    return result;
+}
+
+/** Check whether the stream has an error.
+ *
+ * @param stream to check
+ * @return 1 for error, 0 otherwise
+ */
+static inline int IOStream_error(IOStream *stream){
+    int err = 0;
+    if(stream->methods && stream->methods->error){
+       err = (stream->methods->error)(stream);
+    }
+    return err;
+}
+
+/** Close the stream.
+ *
+ * @param stream to close
+ * @return 0 on success, negative error code otherwise
+ */
+static inline int IOStream_close(IOStream *stream){
+    int err = 0;
+    if(!stream || stream->closed){
+        err = -EIO;
+        goto exit;
+    }
+    if(stream->methods && stream->methods->close){
+        err = (stream->methods->close)(stream);
+        stream->closed = 1;
+    }
+    if(stream->nofree) goto exit;
+    if(stream->methods && stream->methods->free){
+        (stream->methods->free)(stream);
+    }
+    *stream = (IOStream){};
+    deallocate(stream);
+  exit:
+    return err;
+}
+
+/** Test if the stream has been closed.
+ *
+ * @param stream to check
+ * @return 1 if closed, 0 otherwise
+ */
+static inline int IOStream_is_closed(IOStream *stream){
+    return stream->closed;
+}
+
+/** Print a character to a stream, like fputc().
+ *
+ * @param stream to print to
+ * @param c character to print
+ * @return result code from the print
+ */
+static inline int IOStream_putc(IOStream *stream, int c){
+    int err;
+    unsigned char b = (unsigned char)c;
+    err = IOStream_write(stream, &b, 1);
+    if(err < 1){
+        err = IOSTREAM_EOF;
+    } else {
+        err = b;
+    }
+    return err;
+}
+
+/** Read from a stream, like fgetc().
+ *
+ * @param stream to read from
+ * @return IOSTREAM_EOF on error, character read otherwise
+ */
+static inline int IOStream_getc(IOStream *stream){
+    int err, rc;
+    unsigned char b;
+
+    err = IOStream_read(stream, &b, 1);
+    if(err < 1){
+        rc = IOSTREAM_EOF;
+    } else {
+        rc = b;
+    }
+    return rc;
+}
+
+/** Get number of bytes read.
+ *
+ * @param stream to get from
+ * @return number of bytes read
+ */
+static inline int IOStream_get_read(IOStream *stream){
+    return stream->read;
+}
+
+/** Get number of bytes written.
+ *
+ * @param stream to get from
+ * @return number of bytes written
+ */
+static inline int IOStream_get_written(IOStream *stream){
+    return stream->written;
+}
+
+
+#endif /* ! _XUTIL_IOSTREAM_H_ */
diff --git a/tools/vnet/libxutil/kernel_stream.c b/tools/vnet/libxutil/kernel_stream.c
new file mode 100644 (file)
index 0000000..3c6b552
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/** @file
+ * An IOStream implementation using printk() for output.
+ * Input is not implemented.
+ */
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include "kernel_stream.h"
+#include "allocate.h"
+
+/** Number of characters in the output buffer.
+ * The kernel uses 1024 for printk, so that should suffice.
+ */
+#define BUF_N 1024
+
+/** State for a kernel stream. */
+typedef struct KernelData {
+    /** Stream lock. We need a lock to serialize access to the stream. */
+    spinlock_t lock;
+    /** Saved flags for locking. */
+    unsigned long flags;
+    /** Size of the output buffer. */
+    int buf_n;
+    /** Output buffer. */
+    char buf[BUF_N];
+} KernelData;
+
+static int kernel_write(IOStream *s, const void *msg, size_t n);
+static void kernel_free(IOStream *s);
+static void kernel_stream_lock(IOStream *s);
+static void kernel_stream_unlock(IOStream *s);
+
+/** Methods for a kernel stream. Output only. */
+static const IOMethods kernel_methods = {
+    write:  kernel_write,
+    free:   kernel_free,
+    lock:   kernel_stream_lock,
+    unlock: kernel_stream_unlock,
+};
+
+/** Shared state for kernel streams.
+ * All implementations write using printk, so we can use
+ * shared state and avoid allocating it.
+ */
+static const KernelData kernel_data = {
+    lock:  SPIN_LOCK_UNLOCKED,
+    flags: 0,
+    buf_n: BUF_N,
+};
+
+/** Stream for kernel printk. */
+static IOStream iokernel = {
+    methods: &kernel_methods,
+    data:    &kernel_data,
+    nofree:  1,
+};
+
+/** Stream for kernel printk. */
+IOStream *iostdout = &iokernel;
+
+/** Stream for kernel printk. */
+IOStream *iostdin = &iokernel;
+
+/** Stream for kernel printk. */
+IOStream *iostderr = &iokernel;
+
+/** Get an output-only stream implementation using
+ * printk(). The stream uses static storage, and must not be freed.
+ *
+ * @return kernel stream
+ */
+IOStream get_stream_kernel(void){
+    return iokernel;
+}
+
+/** Obtain the lock on the stream state.
+ *
+ * @param kdata stream state
+ */
+static inline void KernelData_lock(KernelData *kdata){
+    spin_lock_irqsave(&kdata->lock, kdata->flags);
+}
+
+/** Release the lock on the stream state.
+ *
+ * @param kdata stream state
+ */
+static inline void KernelData_unlock(KernelData *kdata){
+    spin_unlock_irqrestore(&kdata->lock, kdata->flags);
+}
+
+/** Get the stream state.
+ *
+ * @param s kernel stream
+ * @return stream state
+ */
+static inline KernelData *get_kernel_data(IOStream *s){
+    return (KernelData*)s->data;
+}
+
+/** Obtain the lock on the stream state.
+ *
+ * @param s stream
+ */
+void kernel_stream_lock(IOStream *s){
+    KernelData_lock(get_kernel_data(s));
+}
+
+/** Release the lock on the stream state.
+ *
+ * @param s stream
+ */
+void kernel_stream_unlock(IOStream *s){
+    KernelData_unlock(get_kernel_data(s));
+}
+
+/** Write to a kernel stream.
+ *
+ * @param stream kernel stream
+ * @param format print format
+ * @param args print arguments
+ * @return result of the print
+ */
+static int kernel_write(IOStream *stream, const void *buf, size_t n){
+    KernelData *kdata = get_kernel_data(stream);
+    int k;
+    k = kdata->buf_n - 1;
+    if(n < k) k = n;
+    memcpy(kdata->buf, buf, k);
+    kdata->buf[k] = '\0';
+    printk(kdata->buf);
+    return k;
+}
+
+/** Free a kernel stream.
+ * Frees the internal state of the stream.
+ * Do not call this unless the stream was dynamically allocated.
+ * Do not call this on a stream returned from get_stream_kernel().
+ *
+ * @param io stream to free
+ */
+static void kernel_free(IOStream *io){
+    KernelData *kdata;
+    if(io == &iokernel) return;
+    kdata = get_kernel_data(io);
+    memset(kdata, 0, sizeof(*kdata));
+    deallocate(kdata);
+}
+#endif /* __KERNEL__ */
+
+
+
+
diff --git a/tools/vnet/libxutil/kernel_stream.h b/tools/vnet/libxutil/kernel_stream.h
new file mode 100644 (file)
index 0000000..0f18058
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _XUTIL_KERNEL_STREAM_H_
+#define _XUTIL_KERNEL_STREAM_H_
+
+#ifdef __KERNEL__
+#include "iostream.h"
+
+extern IOStream get_stream_kernel(void);
+#define get_stream_stdout get_stream_kernel
+
+#endif /* __KERNEL__ */
+#endif /* !_XUTIL_KERNEL_STREAM_H_ */
diff --git a/tools/vnet/libxutil/lexis.c b/tools/vnet/libxutil/lexis.c
new file mode 100644 (file)
index 0000000..d3441f0
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or  (at your option) any later version. This library is 
+ * distributed in the  hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+/** @file
+ * Lexical analysis.
+ */
+
+#include "sys_string.h"
+#include "lexis.h"
+#include <errno.h>
+
+/** Check if a value lies in a (closed) range.
+ *
+ * @param x value to test
+ * @param lo low end of the range
+ * @param hi high end of the range
+ * @return 1 if x is in the interval [lo, hi], 0 otherwise
+ */
+inline static int in_range(int x, int lo, int hi){
+    return (lo <= x) && (x <= hi);
+}
+
+/** Determine if a string is an (unsigned) decimal number.
+ * 
+ * @param s pointer to characters to test
+ * @param n length of string
+ * @return 1 if s is a decimal number, 0 otherwise.
+ */
+int is_decimal_number(const char *s, int n){
+    int i;
+    if(n <= 0)return 0;
+    for(i = 0; i < n; i++){
+        if(!in_decimal_digit_class(s[i])) return 0;
+    }
+    return 1;
+}
+
+/** Determine if a string is a hex number.
+ * Hex numbers are 0, or start with 0x or 0X followed
+ * by a non-zero number of hex digits (0-9,a-f,A-F).
+ * 
+ * @param s pointer to characters to test
+ * @param n length of string
+ * @return 1 if s is a hex number, 0 otherwise.
+ */
+int is_hex_number(const char *s, int n){
+    int i;
+    if(n <= 0) return 0;
+    if(n == 1){
+        return s[0]=='0';
+    }
+    if(n <= 3) return 0;
+    if(s[0] != '0' || (s[1] != 'x' && s[1] != 'X')) return 0;
+    for(i = 2; i < n; i++){
+        if(!in_hex_digit_class(s[i])) return 0;
+    }
+    return 1;
+}
+
+/** Test if a string matches a keyword.
+ * The comparison is case-insensitive.
+ * The comparison fails if either argument is null.
+ *
+ * @param s string
+ * @param k keyword
+ * @return 1 if they match, 0 otherwise
+ */
+int is_keyword(const char *s, const char *k){
+  return s && k && !strcasecmp(s, k);
+}
+
+/** Test if a string matches a character.
+ *
+ * @param s string
+ * @param c character (non-null)
+ * @return 1 if s contains exactly c, 0 otherwise
+ */
+int is_keychar(const char *s, char c){
+  return c && (s[0] == c) && !s[1];
+}
diff --git a/tools/vnet/libxutil/lexis.h b/tools/vnet/libxutil/lexis.h
new file mode 100644 (file)
index 0000000..d49a354
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or  (at your option) any later version. This library is 
+ * distributed in the  hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#ifndef _XUTIL_LEXIS_H_
+#define _XUTIL_LEXIS_H_
+
+#include "sys_string.h"
+
+#ifdef __KERNEL__
+#  include <linux/ctype.h>
+#else
+#  include <ctype.h>
+#endif
+
+/** @file
+ * Lexical analysis.
+ */
+
+/** Class of characters treated as space. */
+#define space_class ((char []){ '\n', '\r', '\t', ' ', '\f' , 0 })
+
+/** Class of separator characters. */
+#define sep_class "{}()<>[]!;\"'"
+
+#define comment_class "#"
+
+/** Determine if a character is in a given class.
+ * 
+ * @param c character to test
+ * @param s null-terminated string of characters in the class
+ * @return 1 if c is in the class, 0 otherwise.
+ */
+static inline int in_class(int c, const char *s){
+  return s && (strchr(s, c) != 0);
+}
+
+/** Determine if a character is in the space class.
+ * 
+ * @param c character to test
+ * @return 1 if c is in the class, 0 otherwise.
+ */
+static inline int in_space_class(int c){
+    return in_class(c, space_class);
+}
+
+static inline int in_comment_class(int c){
+    return in_class(c, comment_class);
+}
+
+/** Determine if a character is in the separator class.
+ * Separator characters terminate tokens, and do not need space
+ * to separate them.
+ * 
+ * @param c character to test
+ * @return 1 if c is in the class, 0 otherwise.
+ */
+static inline int in_sep_class(int c){
+    return in_class(c, sep_class);
+}
+
+/** Determine if a character is in the alpha class.
+ * 
+ * @param c character to test
+ * @return 1 if c is in the class, 0 otherwise.
+ */
+static inline int in_alpha_class(int c){
+    return isalpha(c);
+}
+
+/** Determine if a character is in the octal digit class.
+ * 
+ * @param c character to test
+ * @return 1 if c is in the class, 0 otherwise.
+ */
+static inline int in_octal_digit_class(int c){
+    return '0' <= c && c <= '7';
+}
+
+/** Determine if a character is in the decimal digit class.
+ * 
+ * @param c character to test
+ * @return 1 if c is in the class, 0 otherwise.
+ */
+static inline int in_decimal_digit_class(int c){
+    return isdigit(c);
+}
+
+/** Determine if a character is in the hex digit class.
+ * 
+ * @param c character to test
+ * @return 1 if c is in the class, 0 otherwise.
+ */
+static inline int in_hex_digit_class(int c){
+    return isdigit(c) || in_class(c, "abcdefABCDEF");
+}
+
+
+static inline int in_string_quote_class(int c){
+    return in_class(c, "'\"");
+}
+
+static inline int in_printable_class(int c){
+    return ('A' <= c && c <= 'Z')
+        || ('a' <= c && c <= 'z')
+        || ('0' <= c && c <= '9')
+        || in_class(c, "!$%&*+,-./:;<=>?@^_`{|}~");
+}
+
+extern int is_decimal_number(const char *s, int n);
+extern int is_hex_number(const char *s, int n);
+extern int is_keyword(const char *s, const char *k);
+extern int is_keychar(const char *s, char c);
+
+#endif /* !_XUTIL_LEXIS_H_ */
diff --git a/tools/vnet/libxutil/socket_stream.c b/tools/vnet/libxutil/socket_stream.c
new file mode 100644 (file)
index 0000000..9e90b4e
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/** @file
+ * An IOStream implementation using sockets.
+ */
+#ifndef __KERNEL__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include "allocate.h"
+#include "socket_stream.h"
+
+#define MODULE_NAME "sock"
+#define DEBUG 0
+//#undef DEBUG
+#include "debug.h"
+
+static int socket_read(IOStream *s, void *buf, size_t n);
+static int socket_write(IOStream *s, const void *buf, size_t n);
+static int socket_error(IOStream *s);
+static int socket_close(IOStream *s);
+static void socket_free(IOStream *s);
+static int socket_flush(IOStream *s);
+
+/** Methods used by a socket IOStream. */
+static const IOMethods socket_methods = {
+    read:  socket_read,
+    write: socket_write,
+    error: socket_error,
+    close: socket_close,
+    free:  socket_free,
+    flush: socket_flush,
+};
+
+/** Get the socket data.
+ * 
+ * @param io socket stream
+ * @return data
+ */
+static inline SocketData * socket_data(IOStream *io){
+    return (SocketData *)io->data;
+}
+
+/** Test if a stream is a socket stream.
+ *
+ * @param io stream
+ * @return 0 if a socket stream, -EINVAL if not
+ */
+int socket_stream_check(IOStream *io){
+    return (io && io->methods == &socket_methods ? 0 : -EINVAL);
+}
+
+/** Get the data for a socket stream.
+ *
+ * @param io stream
+ * @param data return value for the data
+ * @return 0 if a socket stream, -EINVAL if not
+ */
+int socket_stream_data(IOStream *io, SocketData **data){
+    int err = socket_stream_check(io);
+    if(err){
+        *data = NULL;
+    } else {
+        *data = socket_data(io);
+    }
+    return err;
+}
+
+/** Set the destination address for a socket stream.
+ *
+ * @param io stream
+ * @param addr address
+ * @return 0 if a socket stream, -EINVAL if not
+ */
+int socket_stream_set_addr(IOStream *io, struct sockaddr_in *addr){
+    int err = 0;
+    SocketData *data = NULL;
+    err = socket_stream_data(io, &data);
+    if(!err){
+        data->daddr = *addr;
+    }
+    return err;
+}
+
+/** Set the send flags for a socket stream.
+ *
+ * @param io stream
+ * @param flags flags
+ * @return 0 if a socket stream, -EINVAL if not
+ */
+int socket_stream_set_flags(IOStream *io, int flags){
+    int err = 0;
+    SocketData *data = NULL;
+    err = socket_stream_data(io, &data);
+    if(!err){
+        data->flags = flags;
+    }
+    return err;
+}
+
+/** Write to the underlying socket using sendto.
+ *
+ * @param stream input
+ * @param buf where to put input
+ * @param n number of bytes to write
+ * @return number of bytes written
+ */
+static int socket_write(IOStream *s, const void *buf, size_t n){
+    SocketData *data = socket_data(s);
+    struct sockaddr *daddr = (struct sockaddr *)&data->daddr;
+    socklen_t daddr_n = sizeof(data->daddr);
+    int k;
+    dprintf("> sock=%d addr=%s:%d n=%d\n",
+            data->fd, inet_ntoa(data->daddr.sin_addr), ntohs(data->daddr.sin_port), n);
+    if(0){
+        struct sockaddr_in self = {};
+        socklen_t self_n;
+        getsockname(data->fd, (struct sockaddr *)&self, &self_n);
+        dprintf("> sockname sock=%d %s:%d\n",
+                data->fd, inet_ntoa(self.sin_addr), ntohs(self.sin_port));
+    }
+    k = sendto(data->fd, buf, n, data->flags, daddr, daddr_n);
+    dprintf("> sendto=%d\n", k);
+    return k;
+}
+
+/** Read from the underlying stream using recv();
+ *
+ * @param stream input
+ * @param buf where to put input
+ * @param n number of bytes to read
+ * @return number of bytes read
+ */
+static int socket_read(IOStream *s, void *buf, size_t n){
+    SocketData *data = socket_data(s);
+    int k;
+    struct sockaddr *saddr = (struct sockaddr *)&data->saddr;
+    socklen_t saddr_n = sizeof(data->saddr);
+    k = recvfrom(data->fd, buf, n, data->flags, saddr, &saddr_n);
+    return k;
+}
+
+/** Flush the socket (no-op).
+ *
+ * @param s socket stream
+ * @return 0 on success, error code otherwise
+ */
+static int socket_flush(IOStream *s){
+    return 0;
+}
+
+/** Check if a socket stream has an error (no-op).
+ *
+ * @param s socket stream
+ * @return 1 if has an error, 0 otherwise
+ */
+static int socket_error(IOStream *s){
+    // Read SOL_SOCKET/SO_ERROR ?
+    return 0;
+}
+
+/** Close a socket stream.
+ *
+ * @param s socket stream to close
+ * @return result of the close
+ */
+static int socket_close(IOStream *s){
+    SocketData *data = socket_data(s);
+    return close(data->fd);
+}
+
+/** Free a socket stream.
+ *
+ * @param s socket stream
+ */
+static void socket_free(IOStream *s){
+    SocketData *data = socket_data(s);
+    deallocate(data);
+}
+
+/** Create an IOStream for a socket.
+ *
+ * @param fd socket to wtap
+ * @return new IOStream using fd for i/o
+ */
+IOStream *socket_stream_new(int fd){
+    int err = -ENOMEM;
+    IOStream *io = NULL;
+    SocketData *data = NULL;
+
+    io = ALLOCATE(IOStream);
+    if(!io) goto exit;
+    io->methods = &socket_methods;
+    data = ALLOCATE(SocketData);
+    if(!data) goto exit;
+    io->data = data;
+    data->fd = fd;
+    data->buf_n = sizeof(data->buf);
+    err = 0;
+  exit:
+    if(err){
+        if(io){
+            if(data) deallocate(data);
+            deallocate(io);
+            io = NULL;
+        }
+    }
+    return io;
+}
+
+#endif
diff --git a/tools/vnet/libxutil/socket_stream.h b/tools/vnet/libxutil/socket_stream.h
new file mode 100644 (file)
index 0000000..9da23e9
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _XEN_LIB_SOCKET_STREAM_H_
+#define _XEN_LIB_SOCKET_STREAM_H_
+
+#ifndef __KERNEL__
+#include "iostream.h"
+#include <stdio.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+/** Data associated with a socket stream. */
+typedef struct SocketData {
+    /** The socket file descriptor. */
+    int fd;
+    /** Source address from last read (recvfrom). */
+    struct sockaddr_in saddr;
+    /** Destination address for writes (sendto). */
+    struct sockaddr_in daddr;
+    /** Write flags (sendto). */
+    int flags;
+    /** Buffer size. */
+    int buf_n;
+    /** Buffer for formatted printing. */
+    char buf[1024];
+} SocketData;
+
+extern IOStream *socket_stream_new(int fd);
+extern int socket_stream_data(IOStream *io, SocketData **data);
+extern int socket_stream_check(IOStream *io);
+extern int socket_stream_set_addr(IOStream *io, struct sockaddr_in *addr);
+extern int socket_stream_set_flags(IOStream *io, int flags);
+
+#endif
+#endif /* !_XEN_LIB_SOCKET_STREAM_H_ */
diff --git a/tools/vnet/libxutil/string_stream.c b/tools/vnet/libxutil/string_stream.c
new file mode 100644 (file)
index 0000000..907e7d7
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/** @file
+ * IOStream subtype for input and output to strings.
+ * Usable from user or kernel code (with __KERNEL__ defined).
+ */
+
+#include "sys_string.h"
+#include "string_stream.h"
+#include "allocate.h"
+
+static int string_error(IOStream *io);
+static int string_close(IOStream *io);
+static void string_free(IOStream *io);
+static int string_write(IOStream *io, const void *msg, size_t n);
+static int string_read(IOStream *io, void *buf, size_t n);
+
+/** Methods for a string stream. */
+static IOMethods string_methods = {
+    read:  string_read,
+    write: string_write,
+    error: string_error,
+    close: string_close,
+    free:  string_free,
+};
+
+/** Get the string stream state.
+ *
+ * @param io string stream
+ * @return state
+ */
+static inline StringData *get_string_data(IOStream *io){
+    return (StringData*)io->data;
+}
+
+static int string_write(IOStream *io, const void *msg, size_t n){
+    StringData *data = get_string_data(io);
+    int k;
+
+    k = data->end - data->out;
+    if(n > k) n = k;
+    memcpy(data->out, msg, n);
+    data->out += n;
+    return n;
+}
+
+static int string_read(IOStream *io, void *buf, size_t n){
+    StringData *data = get_string_data(io);
+    int k;
+
+    k = data->end - data->in;
+    if(n > k) n = k;
+    memcpy(buf, data->in, k);
+    data->in += n;
+    return n;
+}
+
+/** Test if a string stream has an error.
+ *
+ * @param io string stream
+ * @return 0 if ok, error code otherwise
+ */
+static int string_error(IOStream *io){
+    StringData *data = get_string_data(io);
+    return data->out == NULL;
+}
+
+/** Close a string stream.
+ *
+ * @param io string stream
+ * @return 0
+ */
+static int string_close(IOStream *io){
+    StringData *data = get_string_data(io);
+    data->in = NULL;
+    data->out = NULL;
+    return 0;
+}
+
+/** Free a string stream.
+ * The stream state is freed, but the underlying string is not.
+ *
+ * @param io string stream
+ */
+static void string_free(IOStream *io){
+    StringData *data = get_string_data(io);
+    memzero(data, sizeof(*data));
+    deallocate(data);
+}
+
+/** Get the methods to use for a string stream.
+ *
+ * @return methods
+ */
+IOMethods *string_stream_get_methods(void){
+    return &string_methods;
+}
+
+/** Initialise a string stream, usually from static data.
+ * If the stream and StringData should be freed when
+ * the stream is closed, unset io->nofree.
+ * The string is not freed on close.
+ *
+ * @param io address of IOStream to fill in
+ * @param data address of StringData to fill in
+ * @param s string to use
+ * @param n length of the string
+ */
+void string_stream_init(IOStream *io, StringData *data, char *s, int n){
+    if(data && io){
+        memzero(data, sizeof(*data));
+        data->string = (char*)s;
+        data->in = data->string;
+        data->out = data->string;
+        data->size = n;
+        data->end = data->string + n;
+        memzero(io, sizeof(*io));
+        io->methods = &string_methods;
+        io->data = data;
+        io->nofree = 1;
+    }
+}
+
+/** Allocate and initialise a string stream.
+ * The stream is freed on close, but the string is not.
+ *
+ * @param s string to use
+ * @param n length of the string
+ * @return new stream (free using IOStream_free)
+ */
+IOStream *string_stream_new(char *s, int n){
+    int ok = 0;
+    StringData *data = ALLOCATE(StringData);
+    IOStream *io = ALLOCATE(IOStream);
+    if(data && io){
+        ok = 1;
+        string_stream_init(io, data, s, n);
+        io->nofree = 0;
+    }
+    if(!ok){
+        deallocate(data);
+        deallocate(io);
+        io = NULL;
+    }
+    return io;
+}
diff --git a/tools/vnet/libxutil/string_stream.h b/tools/vnet/libxutil/string_stream.h
new file mode 100644 (file)
index 0000000..246e63d
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _XUTIL_STRING_STREAM_H_
+#define _XUTIL_STRING_STREAM_H_
+
+#include "iostream.h"
+
+/** Internal state for a string stream.
+ * Exposed here so that string streams can be statically created, using
+ * string_stream_init().
+ */
+typedef struct {
+    /** The string used for input and ouput. */
+    char *string;
+    /** Output pointer. */
+    char *out;
+    /** Input pointer. */
+    char *in;
+    /** Length of string. */
+    int size;
+    /** End marker. */
+    char *end;
+} StringData;
+
+extern IOMethods *string_stream_get_methods(void);
+extern IOStream *string_stream_new(char *s, int n);
+extern void string_stream_init(IOStream *stream, StringData *data, char *s, int n);
+
+#endif /* !_XUTIL_STRING_STREAM_H_ */
diff --git a/tools/vnet/libxutil/sxpr.c b/tools/vnet/libxutil/sxpr.c
new file mode 100644 (file)
index 0000000..d264527
--- /dev/null
@@ -0,0 +1,1230 @@
+/*
+ * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or  (at your option) any later version. This library is 
+ * distributed in the  hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <stdarg.h>
+#include "sys_string.h"
+#include "lexis.h"
+#include "sys_net.h"
+#include "hash_table.h"
+#include "sxpr.h"
+
+#ifdef __KERNEL__
+#include <linux/errno.h>
+#else
+#include <errno.h>
+#endif
+
+#ifdef __KERNEL__
+#include <linux/random.h>
+
+int rand(void){
+    int v;
+    get_random_bytes(&v, sizeof(v));
+    return v;
+}
+
+#else
+#include <stdlib.h>
+#endif
+
+#undef free
+
+/** @file
+ * General representation of sxprs.
+ * Includes print, equal, and free functions for the sxpr types.
+ *
+ * Zero memory containing an Sxpr will have the value ONONE - this is intentional.
+ * When a function returning an sxpr cannot allocate memory we return ONOMEM.
+ *
+ */
+
+static int atom_print(IOStream *io, Sxpr obj, unsigned flags);
+static int atom_equal(Sxpr x, Sxpr y);
+static void atom_free(Sxpr obj);
+static Sxpr atom_copy(Sxpr obj);
+
+static int string_print(IOStream *io, Sxpr obj, unsigned flags);
+static int string_equal(Sxpr x, Sxpr y);
+static void string_free(Sxpr obj);
+static Sxpr string_copy(Sxpr obj);
+
+static int cons_print(IOStream *io, Sxpr obj, unsigned flags);
+static int cons_equal(Sxpr x, Sxpr y);
+static void cons_free(Sxpr obj);
+static Sxpr cons_copy(Sxpr obj);
+
+static int null_print(IOStream *io, Sxpr obj, unsigned flags);
+static int none_print(IOStream *io, Sxpr obj, unsigned flags);
+static int int_print(IOStream *io, Sxpr obj, unsigned flags);
+static int bool_print(IOStream *io, Sxpr obj, unsigned flags);
+static int err_print(IOStream *io, Sxpr obj, unsigned flags);
+static int nomem_print(IOStream *io, Sxpr obj, unsigned flags);
+
+/** Type definitions. */
+static SxprType types[1024] = {
+    [T_NONE]     { .type=    T_NONE,     .name= "none",       .print= none_print      },
+    [T_NULL]     { .type=    T_NULL,     .name= "null",       .print= null_print      },
+    [T_UINT]     { .type=    T_UINT,     .name= "int",        .print= int_print,      },
+    [T_BOOL]     { .type=    T_BOOL,     .name= "bool",       .print= bool_print,     },
+    [T_ERR]      { .type=    T_ERR,      .name= "err",        .print= err_print,      },
+    [T_NOMEM]    { .type=    T_ERR,      .name= "nomem",      .print= nomem_print,    },
+    [T_ATOM]     { .type=    T_ATOM,     .name= "atom",       .print= atom_print,
+                   .pointer= TRUE,
+                   .free=    atom_free,
+                   .equal=   atom_equal,
+                   .copy=    atom_copy,
+                 },
+    [T_STRING]   { .type=    T_STRING,   .name= "string",     .print= string_print,
+                   .pointer= TRUE,
+                   .free=    string_free,
+                   .equal=   string_equal,
+                   .copy=    string_copy,
+                 },
+    [T_CONS]     { .type=    T_CONS,     .name= "cons",       .print= cons_print,
+                   .pointer= TRUE,
+                   .free=    cons_free,
+                   .equal=   cons_equal,
+                   .copy=    cons_copy,
+                 },
+};
+
+/** Number of entries in the types array. */
+static int type_sup = sizeof(types)/sizeof(types[0]);
+
+/** Define a type.
+ * The tydef must have a non-zero type code.
+ * It is an error if the type code is out of range or already defined.
+ *
+ * @param tydef type definition
+ * @return 0 on success, error code otherwise
+ */
+int def_sxpr_type(SxprType *tydef){
+    int err = 0;
+    int ty = tydef->type;
+    if(ty < 0 || ty >= type_sup){
+        err = -EINVAL;
+        goto exit;
+    }
+    if(types[ty].type){
+        err = -EEXIST;
+        goto exit;
+    }
+    types[ty] = *tydef;
+  exit:
+    return err;
+    
+}
+
+/** Get the type definition for a given type code.
+ *
+ * @param ty type code
+ * @return type definition or null
+ */
+SxprType *get_sxpr_type(int ty){
+    if(0 <= ty && ty < type_sup){
+        return types+ty;
+    }
+    return NULL;
+}
+
+/** The default print function.
+ *
+ * @param io stream to print to
+ * @param x sxpr to print
+ * @param flags print flags
+ * @return number of bytes written on success
+ */
+int default_print(IOStream *io, Sxpr x, unsigned flags){
+    return IOStream_print(io, "#<%u %lu>\n", get_type(x), get_ul(x));
+}
+
+/** The default equal function.
+ * Uses eq().
+ *
+ * @param x sxpr to compare
+ * @param y sxpr to compare
+ * @return 1 if equal, 0 otherwise
+ */
+int default_equal(Sxpr x, Sxpr y){
+    return eq(x, y);
+}
+
+/** General sxpr print function.
+ * Prints an sxpr on a stream using the print function for the sxpr type.
+ * Printing is controlled by flags from the PrintFlags enum.
+ * If PRINT_TYPE is in the flags the sxpr type is printed before the sxpr
+ * (for debugging).
+ *
+ * @param io stream to print to
+ * @param x sxpr to print
+ * @param flags print flags
+ * @return number of bytes written
+ */
+int objprint(IOStream *io, Sxpr x, unsigned flags){
+    SxprType *def = get_sxpr_type(get_type(x));
+    ObjPrintFn *print_fn = (def && def->print ? def->print : default_print);
+    int k = 0;
+    if(!io) return k;
+    if(flags & PRINT_TYPE){
+        k += IOStream_print(io, "%s:", def->name);
+    }
+    if(def->pointer && (flags & PRINT_ADDR)){
+        k += IOStream_print(io, "<%p>", get_ptr(x));
+    }
+    k += print_fn(io, x, flags);
+    return k;
+}
+
+Sxpr objcopy(Sxpr x){
+    SxprType *def = get_sxpr_type(get_type(x));
+    ObjCopyFn *copy_fn = (def ? def->copy : NULL);
+    Sxpr v;
+    if(copy_fn){
+        v = copy_fn(x);
+    } else if(def->pointer){
+        v = ONOMEM;
+    } else {
+        v = x;
+    }
+    return v;
+}
+
+/** General sxpr free function.
+ * Frees an sxpr using the free function for its type.
+ * Free functions must recursively free any subsxprs.
+ * If no function is defined then the default is to
+ * free sxprs whose type has pointer true.
+ * Sxprs must not be used after freeing.
+ *
+ * @param x sxpr to free
+ */
+void objfree(Sxpr x){
+    SxprType *def = get_sxpr_type(get_type(x));
+
+    if(def){
+        if(def->free){
+            def->free(x);
+        } else if (def->pointer){
+            hfree(x);
+        }
+    }
+}
+
+/** General sxpr equality function.
+ * Compares x and y using the equal function for x.
+ * Uses default_equal() if x has no equal function.
+ *
+ * @param x sxpr to compare
+ * @param y sxpr to compare
+ * @return 1 if equal, 0 otherwise
+ */
+int objequal(Sxpr x, Sxpr y){
+    SxprType *def = get_sxpr_type(get_type(x));
+    ObjEqualFn *equal_fn = (def && def->equal ? def->equal : default_equal);
+    return equal_fn(x, y);
+}
+
+/** Search for a key in an alist.
+ * An alist is a list of conses, where the cars
+ * of the conses are the keys. Compares keys using equality.
+ *
+ * @param k key
+ * @param l alist to search
+ * @return first element of l with car k, or ONULL
+ */
+Sxpr assoc(Sxpr k, Sxpr l){
+    for( ; CONSP(l) ; l = CDR(l)){
+        Sxpr x = CAR(l);
+        if(CONSP(x) && objequal(k, CAR(x))){
+            return x;   
+        }
+    }
+    return ONULL;
+}
+
+/** Search for a key in an alist.
+ * An alist is a list of conses, where the cars
+ * of the conses are the keys. Compares keys using eq.
+ *
+ * @param k key
+ * @param l alist to search
+ * @return first element of l with car k, or ONULL
+ */
+Sxpr assocq(Sxpr k, Sxpr l){
+    for( ; CONSP(l); l = CDR(l)){
+        Sxpr x = CAR(l);
+        if(CONSP(x) && eq(k, CAR(x))){
+            return x;
+        }
+    }
+    return ONULL;
+}
+
+/** Add a new key and value to an alist.
+ *
+ * @param k key
+ * @param l value
+ * @param l alist
+ * @return l with the new cell added to the front
+ */
+Sxpr acons(Sxpr k, Sxpr v, Sxpr l){
+    Sxpr x, y;
+    x = cons_new(k, v);
+    if(NOMEMP(x)) return x;
+    y = cons_new(x, l);
+    if(NOMEMP(y)) cons_free_cells(x);
+    return y;
+}
+
+/** Test if a list contains an element.
+ * Uses sxpr equality.
+ *
+ * @param l list
+ * @param x element to look for
+ * @return a tail of l with x as car, or ONULL
+ */
+Sxpr cons_member(Sxpr l, Sxpr x){
+    for( ; CONSP(l) && !eq(x, CAR(l)); l = CDR(l)){}
+    return l;
+}
+
+/** Test if a list contains an element satisfying a test.
+ * The test function is called with v and an element of the list.
+ *
+ * @param l list
+ * @param test_fn test function to use
+ * @param v value for first argument to the test
+ * @return a tail of l with car satisfying the test, or 0
+ */
+Sxpr cons_member_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v){
+    for( ; CONSP(l) && !test_fn(v, CAR(l)); l = CDR(l)){ }
+    return l;
+}
+
+/** Test if the elements of list 't' are a subset of the elements
+ * of list 's'. Element order is not significant.
+ *
+ * @param s element list to check subset of
+ * @param t element list to check if is a subset
+ * @return 1 if is a subset, 0 otherwise
+ */
+int cons_subset(Sxpr s, Sxpr t){
+    for( ; CONSP(t); t = CDR(t)){
+        if(!CONSP(cons_member(s, CAR(t)))){
+            return 0;
+        }
+    }
+    return 1;
+}
+
+/** Test if two lists have equal sets of elements.
+ * Element order is not significant.
+ *
+ * @param s list to check
+ * @param t list to check
+ * @return 1 if equal, 0 otherwise
+ */
+int cons_set_equal(Sxpr s, Sxpr t){
+    return cons_subset(s, t) && cons_subset(t, s);
+}
+
+#ifdef USE_GC
+/*============================================================================*/
+/* The functions inside this ifdef are only safe if GC is used.
+ * Otherwise they may leak memory.
+ */
+
+/** Remove an element from a list (GC only).
+ * Uses sxpr equality and removes all instances, even
+ * if there are more than one.
+ *
+ * @param l list to remove elements from
+ * @param x element to remove
+ * @return modified input list
+ */
+Sxpr cons_remove(Sxpr l, Sxpr x){
+    return cons_remove_if(l, eq, x);
+}
+
+/** Remove elements satisfying a test (GC only).
+ * The test function is called with v and an element of the set.
+ *
+ * @param l list to remove elements from
+ * @param test_fn function to use to decide if an element should be removed
+ * @return modified input list
+ */
+Sxpr cons_remove_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v){
+    Sxpr prev = ONULL, elt, next;
+
+    for(elt = l; CONSP(elt); elt = next){
+        next = CDR(elt);
+        if(test_fn(v, CAR(elt))){
+            if(NULLP(prev)){
+                l = next;
+            } else {
+                CDR(prev) = next;
+            }
+        }
+    }
+    return l;
+}
+
+/** Set the value for a key in an alist (GC only).
+ * If the key is present, changes the value, otherwise
+ * adds a new cell.
+ *
+ * @param k key
+ * @param v value
+ * @param l alist
+ * @return modified or extended list
+ */
+Sxpr setf(Sxpr k, Sxpr v, Sxpr l){
+    Sxpr e = assoc(k, l);
+    if(NULLP(e)){
+        l = acons(k, v, l);
+    } else {
+        CAR(CDR(e)) = v;
+    }
+    return l;
+}
+/*============================================================================*/
+#endif /* USE_GC */
+
+/** Create a new atom with the given name.
+ * Makes an integer sxpr if the name can be parsed as an int.
+ *
+ * @param name the name
+ * @return new atom
+ */
+Sxpr atom_new(char *name){
+    Sxpr n, obj = ONOMEM;
+    long v;
+
+    if(convert_atol(name, &v) == 0){
+        obj = OINT(v);
+    } else {
+        n = string_new(name);
+        if(NOMEMP(n)) goto exit;
+        obj = HALLOC(ObjAtom, T_ATOM);
+        if(NOMEMP(obj)){
+            string_free(n);
+            goto exit;
+        }
+        OBJ_ATOM(obj)->name = n;
+    }
+  exit:
+    return obj;
+}
+
+/** Free an atom.
+ *
+ * @param obj to free
+ */
+void atom_free(Sxpr obj){
+    // Interned atoms are shared, so do not free.
+    if(OBJ_ATOM(obj)->interned) return;
+    objfree(OBJ_ATOM(obj)->name);
+    hfree(obj);
+}
+
+/** Copy an atom.
+ *
+ * @param obj to copy
+ */
+Sxpr atom_copy(Sxpr obj){
+    Sxpr v;
+    if(OBJ_ATOM(obj)->interned){
+        v = obj;
+    } else {
+        v = atom_new(atom_name(obj));
+    }
+    return v;
+}
+
+/** Print an atom. Prints the atom name.
+ *
+ * @param io stream to print to
+ * @param obj to print
+ * @param flags print flags
+ * @return number of bytes printed
+ */
+int atom_print(IOStream *io, Sxpr obj, unsigned flags){
+    return objprint(io, OBJ_ATOM(obj)->name, flags);
+}
+
+/** Atom equality.
+ *
+ * @param x to compare
+ * @param y to compare
+ * @return 1 if equal, 0 otherwise
+ */
+int atom_equal(Sxpr x, Sxpr y){
+    int ok;
+    ok = eq(x, y);
+    if(ok) goto exit;
+    ok = ATOMP(y) && string_equal(OBJ_ATOM(x)->name, OBJ_ATOM(y)->name);
+    if(ok) goto exit;
+    ok = STRINGP(y) && string_equal(OBJ_ATOM(x)->name, y);
+  exit:
+    return ok;
+}
+
+/** Get the name of an atom.
+ *
+ * @param obj atom
+ * @return name
+ */
+char * atom_name(Sxpr obj){
+    return string_string(OBJ_ATOM(obj)->name);
+}
+
+int atom_length(Sxpr obj){
+    return string_length(OBJ_ATOM(obj)->name);
+}
+
+/** Get the C string from a string sxpr.
+ *
+ * @param obj string sxpr
+ * @return string
+ */
+char * string_string(Sxpr obj){
+    return OBJ_STRING(obj)->data;
+}
+
+/** Get the length of a string.
+ *
+ * @param obj string
+ * @return length
+ */
+int string_length(Sxpr obj){
+    return OBJ_STRING(obj)->len;
+}
+
+/** Create a new string. The input string is copied,
+ * and must be null-terminated.
+ *
+ * @param s characters to put in the string
+ * @return new sxpr
+ */
+Sxpr string_new(char *s){
+    int n = (s ? strlen(s) : 0);
+    return string_new_n(s, n);
+}
+
+/** Create a new string. The input string is copied,
+ * and need not be null-terminated.
+ *
+ * @param s characters to put in the string (may be null)
+ * @param n string length
+ * @return new sxpr
+ */
+Sxpr string_new_n(char *s, int n){
+    Sxpr obj;
+    obj = halloc(sizeof(ObjString) + n + 1, T_STRING);
+    if(!NOMEMP(obj)){
+        char *str = OBJ_STRING(obj)->data;
+        OBJ_STRING(obj)->len = n;
+        if(s){
+            memcpy(str, s, n);
+            str[n] = '\0';
+        } else {
+            memset(str, 0, n + 1);
+        }
+    }
+    return obj;
+}
+
+/** Free a string.
+ *
+ * @param obj to free
+ */
+void string_free(Sxpr obj){
+    hfree(obj);
+}
+
+/** Copy a string.
+ *
+ * @param obj to copy
+ */
+Sxpr string_copy(Sxpr obj){
+    return string_new_n(string_string(obj), string_length(obj));
+}
+
+/** Determine if a string needs escapes when printed
+ * using the given flags.
+ *
+ * @param str string to check
+ * @param n string length
+ * @param flags print flags
+ * @return 1 if needs escapes, 0 otherwise
+ */
+int needs_escapes(char *str, int n, unsigned flags){
+    char *c;
+    int i;
+    int val = 0;
+
+    if(str){
+        for(i=0, c=str; i<n; i++, c++){
+            if(in_alpha_class(*c)) continue;
+            if(in_decimal_digit_class(*c)) continue;
+            if(in_class(*c, "/._+:@~-")) continue;
+            val = 1;
+            break;
+        }
+    }
+    return val;
+}
+
+char randchar(void){
+    int r;
+    char c;
+    for( ; ; ){
+        r = rand();
+        c = (r >> 16) & 0xff;
+        if('a' <= c && c <= 'z') break;
+    }
+    return c;
+}
+
+int string_contains(char *s, int s_n, char *k, int k_n){
+    int i, n = s_n - k_n;
+    for(i=0; i < n; i++){
+        if(!memcmp(s+i, k, k_n)) return 1;
+    }
+    return 0;
+}
+
+int string_delim(char *s, int s_n, char *d, int d_n){
+    int i;
+    if(d_n < 4) return -1;
+    memset(d, 0, d_n+1);
+    for(i=0; i<3; i++){
+        d[i] = randchar();
+    }
+    for( ; i < d_n; i++){
+        if(!string_contains(s, s_n, d, i)){
+            return i;
+        }
+        d[i] = randchar();
+    }
+    return -1;
+}
+
+/** Print the bytes in a string as-is.
+ *
+ * @param io stream
+ * @param str string
+ * @param n length
+ * @return bytes written or error code
+ */
+int _string_print_raw(IOStream *io, char *str, int n){
+    int k = 0;
+    k = IOStream_write(io, str, n);
+    return k;
+}
+
+/** Print a string in counted data format.
+ *
+ * @param io stream
+ * @param str string
+ * @param n length
+ * @return bytes written or error code
+ */
+int _string_print_counted(IOStream *io, char *str, int n){
+    int k = 0;
+    k += IOStream_print(io, "%c%c%d%c",
+                        c_data_open, c_data_count, n, c_data_count);
+    k += IOStream_write(io, str, n);
+    return k;
+}
+  
+/** Print a string in quoted data format.
+ *
+ * @param io stream
+ * @param str string
+ * @param n length
+ * @return bytes written or error code
+ */
+int _string_print_quoted(IOStream *io, char *str, int n){
+    int k = 0;
+    char d[10];
+    int d_n;
+    d_n = string_delim(str, n, d, sizeof(d) - 1);
+    k += IOStream_print(io, "%c%c%s%c",
+                        c_data_open, c_data_quote, d, c_data_quote);
+    k += IOStream_write(io, str, n);
+    k += IOStream_print(io, "%c%s%c", c_data_quote, d, c_data_quote);
+    return k;
+}
+
+/** Print a string as a quoted string.
+ *
+ * @param io stream
+ * @param str string
+ * @param n length
+ * @return bytes written or error code
+ */
+int _string_print_string(IOStream *io, char *str, int n){
+    int k = 0;
+    
+    k += IOStream_print(io, "\"");
+    if(str){
+        char *s, *t;
+        for(s = str, t = str + n; s < t; s++){
+            if(*s < ' ' || *s >= 127 ){
+                switch(*s){
+                case '\a': k += IOStream_print(io, "\\a");  break;
+                case '\b': k += IOStream_print(io, "\\b");  break;
+                case '\f': k += IOStream_print(io, "\\f");  break;
+                case '\n': k += IOStream_print(io, "\\n");  break;
+                case '\r': k += IOStream_print(io, "\\r");  break;
+                case '\t': k += IOStream_print(io, "\\t");  break;
+                case '\v': k += IOStream_print(io, "\\v");  break;
+                default:
+                    // Octal escape;
+                    k += IOStream_print(io, "\\%o", *s);
+                    break;
+                }
+            } else if(*s == c_double_quote ||
+                      *s == c_single_quote ||
+                      *s == c_escape){
+                k += IOStream_print(io, "\\%c", *s);
+            } else {
+                k+= IOStream_print(io, "%c", *s);
+            }
+        }
+    }
+    k += IOStream_print(io, "\"");
+    return k;
+}
+
+/** Print a string to a stream, with escapes if necessary.
+ *
+ * @param io stream to print to
+ * @param str string
+ * @param n string length
+ * @param flags print flags
+ * @return number of bytes written
+ */
+int _string_print(IOStream *io, char *str, int n, unsigned flags){
+    int k = 0;
+    if((flags & PRINT_COUNTED)){
+        k = _string_print_counted(io, str, n);
+    } else if((flags & PRINT_RAW) || !needs_escapes(str, n, flags)){
+        k = _string_print_raw(io, str, n);
+    } else if(n > 50){
+        k = _string_print_quoted(io, str, n);
+    } else {
+        k = _string_print_string(io, str, n);
+    }
+    return k;
+}
+
+/** Print a string to a stream, with escapes if necessary.
+ *
+ * @param io stream to print to
+ * @param obj string
+ * @param flags print flags
+ * @return number of bytes written
+ */
+int string_print(IOStream *io, Sxpr obj, unsigned flags){
+    return _string_print(io,
+                         OBJ_STRING(obj)->data,
+                         OBJ_STRING(obj)->len,
+                         flags);
+}
+
+int string_eq(char *s, int s_n, char *t, int t_n){
+    return (s_n == t_n) && (memcmp(s, t, s_n) == 0);
+}
+
+/** Compare an sxpr with a string for equality.
+ *
+ * @param x string to compare with
+ * @param y sxpr to compare
+ * @return 1 if equal, 0 otherwise
+ */
+int string_equal(Sxpr x, Sxpr y){
+    int ok = 0;
+    ok = eq(x,y);
+    if(ok) goto exit;
+    ok = has_type(y, T_STRING) &&
+        string_eq(OBJ_STRING(x)->data, OBJ_STRING(x)->len,
+                  OBJ_STRING(y)->data, OBJ_STRING(y)->len);
+    if(ok) goto exit;
+    ok = has_type(y, T_ATOM) &&
+        string_eq(OBJ_STRING(x)->data, OBJ_STRING(x)->len,
+                  atom_name(y), atom_length(y));
+  exit:
+    return ok;
+}
+
+/** Create a new cons cell.
+ * The cell is ONOMEM if either argument is.
+ *
+ * @param car sxpr for the car
+ * @param cdr sxpr for the cdr
+ * @return new cons
+ */
+Sxpr cons_new(Sxpr car, Sxpr cdr){
+    Sxpr obj;
+    if(NOMEMP(car) || NOMEMP(cdr)){
+        obj = ONOMEM;
+    } else {
+        obj = HALLOC(ObjCons, T_CONS);
+        if(!NOMEMP(obj)){
+            ObjCons *z = OBJ_CONS(obj);
+            z->car = car;
+            z->cdr = cdr;
+        }
+    }
+    return obj;
+}
+
+/** Push a new element onto a list.
+ *
+ * @param list list to add to
+ * @param elt element to add
+ * @return 0 if successful, error code otherwise
+ */
+int cons_push(Sxpr *list, Sxpr elt){
+    Sxpr l;
+    l = cons_new(elt, *list);
+    if(NOMEMP(l)) return -ENOMEM;
+    *list = l;
+    return 0;
+}
+
+/** Free a cons. Recursively frees the car and cdr.
+ *
+ * @param obj to free
+ */
+void cons_free(Sxpr obj){
+    Sxpr next;
+    for(; CONSP(obj); obj = next){
+        next = CDR(obj);
+        objfree(CAR(obj));
+        hfree(obj);
+    }
+    if(!NULLP(obj)){
+        objfree(obj);
+    }
+}
+
+/** Copy a cons. Recursively copies the car and cdr.
+ *
+ * @param obj to copy
+ */
+Sxpr cons_copy(Sxpr obj){
+    Sxpr v = ONULL;
+    Sxpr l = ONULL, x = ONONE;
+    for(l = obj; CONSP(l); l = CDR(l)){
+        x = objcopy(CAR(l));
+        if(NOMEMP(x)) goto exit;
+        x = cons_new(x, v);
+        if(NOMEMP(x)) goto exit;
+        v = x;
+    }
+    v = nrev(v);
+  exit:
+    if(NOMEMP(x)){
+        objfree(v);
+        v = ONOMEM;
+    }
+    return v;
+}
+
+/** Free a cons and its cdr cells, but not the car sxprs.
+ * Does nothing if called on something that is not a cons.
+ *
+ * @param obj to free
+ */
+void cons_free_cells(Sxpr obj){
+    Sxpr next;
+    for(; CONSP(obj); obj = next){
+        next = CDR(obj);
+        hfree(obj);
+    }
+}
+
+/** Print a cons.
+ * Prints the cons in list format if the cdrs are conses.
+ * uses pair (dot) format if the last cdr is not a cons (or null).
+ *
+ * @param io stream to print to
+ * @param obj to print
+ * @param flags print flags
+ * @return number of bytes written
+ */
+int cons_print(IOStream *io, Sxpr obj, unsigned flags){
+    int first = 1;
+    int k = 0;
+    k += IOStream_print(io, "(");
+    for( ; CONSP(obj) ; obj = CDR(obj)){
+        if(first){ 
+            first = 0;
+        } else {
+            k += IOStream_print(io, " ");
+        }
+        k += objprint(io, CAR(obj), flags);
+    }
+    if(!NULLP(obj)){
+        k += IOStream_print(io, " . ");
+        k += objprint(io, obj, flags);
+    }
+    k += IOStream_print(io, ")");
+    return (IOStream_error(io) ? -1 : k);
+}
+
+/** Compare a cons with another sxpr for equality.
+ * If y is a cons, compares the cars and cdrs recursively.
+ *
+ * @param x cons to compare
+ * @param y sxpr to compare
+ * @return 1 if equal, 0 otherwise
+ */
+int cons_equal(Sxpr x, Sxpr y){
+    return CONSP(y) &&
+        objequal(CAR(x), CAR(y)) &&
+        objequal(CDR(x), CDR(y));
+}
+
+/** Return the length of a cons list.
+ *
+ * @param obj list
+ * @return length
+ */
+int cons_length(Sxpr obj){
+    int count = 0;
+    for( ; CONSP(obj); obj = CDR(obj)){
+        count++;
+    }
+    return count;
+}
+
+/** Destructively reverse a cons list in-place.
+ * If the argument is not a cons it is returned unchanged.
+ * 
+ * @param l to reverse
+ * @return reversed list
+ */
+Sxpr nrev(Sxpr l){
+    if(CONSP(l)){
+        // Iterate down the cells in the list making the cdr of
+        // each cell point to the previous cell. The last cell 
+        // is the head of the reversed list.
+        Sxpr prev = ONULL;
+        Sxpr cell = l;
+        Sxpr next;
+
+        while(1){
+            next = CDR(cell);
+            CDR(cell) = prev;
+            if(!CONSP(next)) break;
+            prev = cell;
+            cell = next;
+        }
+        l = cell;
+    }
+    return l;
+}
+
+/** Print the null sxpr.        
+ *
+ * @param io stream to print to
+ * @param obj to print
+ * @param flags print flags
+ * @return number of bytes written
+ */
+static int null_print(IOStream *io, Sxpr obj, unsigned flags){
+    return IOStream_print(io, "()");
+}
+
+/** Print the `unspecified' sxpr none.
+ *
+ * @param io stream to print to
+ * @param obj to print
+ * @param flags print flags
+ * @return number of bytes written
+ */
+static int none_print(IOStream *io, Sxpr obj, unsigned flags){
+    return IOStream_print(io, "<none>");
+}
+
+/** Print an integer.
+ *
+ * @param io stream to print to
+ * @param obj to print
+ * @param flags print flags
+ * @return number of bytes written
+ */
+static int int_print(IOStream *io, Sxpr obj, unsigned flags){
+    return IOStream_print(io, "%d", OBJ_INT(obj));
+}
+
+/** Print a boolean.
+ *
+ * @param io stream to print to
+ * @param obj to print
+ * @param flags print flags
+ * @return number of bytes written
+ */
+static int bool_print(IOStream *io, Sxpr obj, unsigned flags){
+    return IOStream_print(io, (OBJ_UINT(obj) ? k_true : k_false));
+}
+
+/** Print an error.
+ *
+ * @param io stream to print to
+ * @param obj to print
+ * @param flags print flags
+ * @return number of bytes written
+ */
+static int err_print(IOStream *io, Sxpr obj, unsigned flags){
+    int err = OBJ_INT(obj);
+    if(err < 0) err = -err;
+    return IOStream_print(io, "[error:%d:%s]", err, strerror(err));
+}
+
+/** Print the 'nomem' sxpr.
+ *
+ * @param io stream to print to
+ * @param obj to print
+ * @param flags print flags
+ * @return number of bytes written
+ */
+static int nomem_print(IOStream *io, Sxpr obj, unsigned flags){
+    return IOStream_print(io, "[ENOMEM]");
+}
+
+int sxprp(Sxpr obj, Sxpr name){
+    return CONSP(obj) && objequal(CAR(obj), name);
+}
+
+/** Get the name of an element.
+ * 
+ * @param obj element
+ * @return name
+ */
+Sxpr sxpr_name(Sxpr obj){
+    Sxpr val = ONONE;
+    if(CONSP(obj)){
+        val = CAR(obj);
+    } else if(STRINGP(obj) || ATOMP(obj)){
+        val = obj;
+    }
+    return val;
+}
+
+int sxpr_is(Sxpr obj, char *s){
+    if(ATOMP(obj)) return string_eq(atom_name(obj), atom_length(obj), s, strlen(s));
+    if(STRINGP(obj)) return string_eq(string_string(obj), string_length(obj), s, strlen(s));
+    return 0;
+}
+
+int sxpr_elementp(Sxpr obj, Sxpr name){
+    int ok = 0;
+    ok = CONSP(obj) && objequal(CAR(obj), name);
+    return ok;
+}
+
+/** Get the attributes of an sxpr.
+ * 
+ * @param obj sxpr
+ * @return attributes
+ */
+Sxpr sxpr_attributes(Sxpr obj){
+    Sxpr val = ONULL;
+    if(CONSP(obj)){
+        obj = CDR(obj);
+        if(CONSP(obj)){
+            obj = CAR(obj);
+            if(sxprp(obj, intern("@"))){
+                val = CDR(obj);
+            }
+        }
+    }
+    return val;
+}
+
+Sxpr sxpr_attribute(Sxpr obj, Sxpr key, Sxpr def){
+    Sxpr val = ONONE;
+    val = assoc(sxpr_attributes(obj), key);
+    if(CONSP(val) && CONSP(CDR(val))){
+        val = CADR(def);
+    } else {
+        val = def;
+    }
+    return val;
+}
+
+/** Get the children of an sxpr.
+ * 
+ * @param obj sxpr
+ * @return children
+ */
+Sxpr sxpr_children(Sxpr obj){
+    Sxpr val = ONULL;
+    if(CONSP(obj)){
+        val = CDR(obj);
+        if(CONSP(val) && sxprp(CAR(val), intern("@"))){
+            val = CDR(val);
+        }
+    }
+    return val;
+}
+
+Sxpr sxpr_child(Sxpr obj, Sxpr name, Sxpr def){
+    Sxpr val = ONONE;
+    Sxpr l;
+    for(l = sxpr_children(obj); CONSP(l); l = CDR(l)){
+        if(sxprp(CAR(l), name)){
+            val = CAR(l);
+            break;
+        }
+    }
+    if(NONEP(val)) val = def;
+    return val;
+}
+
+Sxpr sxpr_child0(Sxpr obj, Sxpr def){
+    Sxpr val = ONONE;
+    Sxpr l = sxpr_children(obj);
+    if(CONSP(l)){
+        val = CAR(l);
+    } else {
+        val = def;
+    }
+    return val;
+}
+
+Sxpr sxpr_childN(Sxpr obj, int n, Sxpr def){
+    Sxpr val = def;
+    Sxpr l;
+    int i;
+    for (i = 0, l = sxpr_children(obj); CONSP(l); i++, l = CDR(l)){
+        if(i == n){
+            val = CAR(l);
+            break;
+        }
+    }
+    return val;
+}
+    
+Sxpr sxpr_child_value(Sxpr obj, Sxpr name, Sxpr def){
+    Sxpr val = ONONE;
+    val = sxpr_child(obj, name, ONONE);
+    if(NONEP(val)){
+        val = def;
+    } else {
+        val = sxpr_child0(val, def);
+    }
+    return val;
+}
+
+/** Table of interned symbols. Indexed by symbol name. */
+static HashTable *symbols = NULL;
+
+/** Hash function for entries in the symbol table.
+ *
+ * @param key to hash
+ * @return hashcode
+ */
+static Hashcode sym_hash_fn(void *key){
+    return hash_string((char*)key);
+}
+
+/** Key equality function for the symbol table.
+ *
+ * @param x to compare
+ * @param y to compare
+ * @return 1 if equal, 0 otherwise
+ */
+static int sym_equal_fn(void *x, void *y){
+    return !strcmp((char*)x, (char*)y);
+}
+
+/** Entry free function for the symbol table.
+ *
+ * @param table the entry is in
+ * @param entry being freed
+ */
+static void sym_free_fn(HashTable *table, HTEntry *entry){
+    if(entry){
+        objfree(((ObjAtom*)entry->value)->name);
+        HTEntry_free(entry);
+    }
+}
+        
+/** Initialize the symbol table.
+ *
+ * @return 0 on sucess, error code otherwise
+ */
+static int init_symbols(void){
+    symbols = HashTable_new(100);
+    if(symbols){
+        symbols->key_hash_fn = sym_hash_fn;
+        symbols->key_equal_fn = sym_equal_fn;
+        symbols->entry_free_fn = sym_free_fn;
+        return 0;
+    }
+    return -1;
+}
+
+/** Cleanup the symbol table. Frees the table and all its symbols.
+ */
+void cleanup_symbols(void){
+    HashTable_free(symbols);
+    symbols = NULL;
+}
+
+/** Get the interned symbol with the given name.
+ * No new symbol is created.
+ *
+ * @return symbol or null
+ */
+Sxpr get_symbol(char *sym){
+    HTEntry *entry;
+    if(!symbols){
+        if(init_symbols()) return ONOMEM;
+        return ONULL;
+    }
+    entry = HashTable_get_entry(symbols, sym);
+    if(entry){
+        return OBJP(T_ATOM, entry->value);
+    } else {
+        return ONULL;
+    }
+}
+
+/** Get the interned symbol with the given name.
+ * Creates a new symbol if necessary.
+ *
+ * @return symbol
+ */
+Sxpr intern(char *sym){
+    Sxpr symbol = get_symbol(sym);
+    if(NULLP(symbol)){
+        if(!symbols) return ONOMEM;
+        symbol = atom_new(sym);
+        if(!NOMEMP(symbol)){
+            OBJ_ATOM(symbol)->interned = TRUE;
+            HashTable_add(symbols, atom_name(symbol), get_ptr(symbol));
+        }
+    }
+    return symbol;
+}
diff --git a/tools/vnet/libxutil/sxpr.h b/tools/vnet/libxutil/sxpr.h
new file mode 100644 (file)
index 0000000..c9acd7b
--- /dev/null
@@ -0,0 +1,437 @@
+/*
+ * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or  (at your option) any later version. This library is 
+ * distributed in the  hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+#ifndef _XUTIL_SXPR_H_
+#define _XUTIL_SXPR_H_
+
+#ifdef __KERNEL__
+#include <linux/config.h>
+#include <linux/types.h>
+#else
+#include <stdint.h>
+#endif
+
+#include "hash_table.h"
+#include "iostream.h"
+#include "allocate.h"
+
+/** @file
+ * Definitions for rules and sxprs.
+ */
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/** Sxpr type. */
+typedef int16_t TypeCode;
+
+/** A typed sxpr handle.*/
+typedef struct Sxpr {
+    /** Sxpr type. */
+    TypeCode type;
+    union {
+        /** Sxpr value. */
+        unsigned long ul;
+        /** Pointer. */
+        void *ptr;
+    } v;
+} Sxpr;
+
+/** Get the integer value from an sxpr.
+ *
+ * @param obj sxpr
+ * @return value
+ */
+static inline unsigned long get_ul(Sxpr obj){
+    return obj.v.ul;
+}
+
+/** Get the pointer value from an sxpr.
+ *
+ * @param obj sxpr
+ * @return value
+ */
+static inline void * get_ptr(Sxpr obj){
+    return obj.v.ptr;
+}
+
+/** Create an sxpr containing a pointer.
+ *
+ * @param ty typecode
+ * @param val pointer
+ * @return sxpr
+ */
+static inline Sxpr obj_ptr(TypeCode ty, void *val){
+    return (Sxpr){ .type= ty, .v= { .ptr= val } };
+}
+
+/** Create an sxpr containing an integer.
+ *
+ * @param ty typecode
+ * @param val integer
+ * @return sxpr
+ */
+static inline Sxpr obj_ul(TypeCode ty, unsigned long val){
+    return (Sxpr){ .type= ty, .v= { .ul= val } };
+}
+
+/** Get the type of an sxpr.
+ *
+ * @param obj sxpr
+ * @return type
+ */
+static inline TypeCode get_type(Sxpr obj){
+    return obj.type;
+}
+
+/** Check the type of an sxpr.
+ *
+ * @param obj sxpr
+ * @param type to check
+ * @return 1 if has the type, 0 otherwise
+ */
+static inline int has_type(Sxpr obj, TypeCode type){
+    return get_type(obj) == type;
+}
+
+/** Compare sxprs for literal equality of type and value.
+ *
+ * @param x sxpr to compare
+ * @param y sxpr to compare
+ * @return 1 if equal, 0 otherwise
+ */
+static inline int eq(Sxpr x, Sxpr y){
+    return ((get_type(x) == get_type(y)) && (get_ul(x) == get_ul(y)));
+}
+
+/** The 'unspecified' sxpr. */
+#define T_NONE       ((TypeCode)0)
+/** The empty list. */
+#define T_NULL       ((TypeCode)1)
+/** Unsigned integer. */
+#define T_UINT       ((TypeCode)2)
+/** A string. */
+#define T_STRING     ((TypeCode)3)
+/** An atom. */
+#define T_ATOM       ((TypeCode)4)
+/** A boolean. */
+#define T_BOOL       ((TypeCode)5)
+
+/** A cons (pair or list). */
+#define T_CONS       ((TypeCode)10)
+
+/** An error. */
+#define T_ERR        ((TypeCode)40)
+/** Sxpr type to indicate out of memory. */
+#define T_NOMEM      ((TypeCode)41)
+
+typedef struct ObjString {
+    int len;
+    char data[];
+} ObjString;
+
+/** An atom. */
+typedef struct ObjAtom {
+    Sxpr name;
+    Hashcode hashcode;
+    int interned;
+} ObjAtom;
+
+/** A cons (pair). */
+typedef struct ObjCons {
+    Sxpr car;
+    Sxpr cdr;
+} ObjCons;
+
+/** Flags for sxpr printing. */
+enum PrintFlags {
+    PRINT_RAW           = 0x001,
+    PRINT_TYPE          = 0x002,
+    PRINT_PRETTY        = 0x004,
+    PRINT_COUNTED       = 0x008,
+    PRINT_ADDR          = 0x010,
+};
+
+extern int _string_print(IOStream *io, char *str, int n, unsigned flags);
+extern int _string_print_raw(IOStream *io, char *str, int n);
+extern int _string_print_counted(IOStream *io, char *str, int n);
+extern int _string_print_quoted(IOStream *io, char *str, int n);
+extern int _string_print_string(IOStream *io, char *str, int n);
+
+/** An integer sxpr.
+ *
+ * @param ty type
+ * @param val integer value
+ */
+#define OBJI(ty, val) obj_ul(ty, val)
+
+/** Make an integer sxpr.
+ * @param x value
+ */
+#define OINT(x)       OBJI(T_UINT,  x)
+
+/** Make an error sxpr.
+ *
+ * @param x value
+ */
+#define OERR(x)       OBJI(T_ERR,   x)
+
+/** Out of memory constant. */
+#define ONOMEM        OBJI(T_NOMEM, 0)
+
+/** The `unspecified' constant. */
+#define ONONE         OBJI(T_NONE,  0)
+
+/** Empty list constant. */
+#define ONULL         OBJI(T_NULL,  0)
+
+/** False constant. */
+#define OFALSE        OBJI(T_BOOL,  0)
+
+/** True constant. */
+#define OTRUE         OBJI(T_BOOL,  1)
+
+/** A pointer sxpr.
+ * If the pointer is non-null, returns an sxpr containing it.
+ * If the pointer is null, returns ONOMEM.
+ *
+ * @param ty type
+ * @param val pointer
+ */
+static inline Sxpr OBJP(int ty, void *val){
+    return (val ? obj_ptr(ty, val) : ONOMEM);
+}
+
+/** Make an integer sxpr containing a pointer.
+ *
+ * @param val pointer
+ */
+#define PTR(val) OBJP(T_UINT, (void*)(val))
+
+/** Allocate some memory and return an sxpr containing it.
+ * Returns ONOMEM if allocation failed.
+ *
+ * @param n number of bytes to allocate
+ * @param ty typecode
+ * @return sxpr
+ */
+#define halloc(_n, _ty) OBJP(_ty, allocate(_n))
+
+/** Allocate an sxpr containing a pointer to the given type.
+ *
+ * @param _ctype type (uses sizeof to determine how many bytes to allocate)
+ * @param _tycode typecode
+ * @return sxpr, ONOMEM if allocation failed
+ */
+#define HALLOC(_ctype, _tycode) halloc(sizeof(_ctype), _tycode)
+
+/* Recognizers for the various sxpr types.  */
+#define ATOMP(obj)        has_type(obj, T_ATOM)
+#define BOOLP(obj)        has_type(obj, T_BOOL)
+#define CONSP(obj)        has_type(obj, T_CONS)
+#define ERRP(obj)         has_type(obj, T_ERR)
+#define INTP(obj)         has_type(obj, T_UINT)
+#define NOMEMP(obj)       has_type(obj, T_NOMEM)
+#define NONEP(obj)        has_type(obj, T_NONE)
+#define NULLP(obj)        has_type(obj, T_NULL)
+#define STRINGP(obj)      has_type(obj, T_STRING)
+
+#define TRUEP(obj)    get_ul(obj)
+
+/** Convert an sxpr to an unsigned integer. */
+#define OBJ_UINT(x)   get_ul(x)
+/** Convert an sxpr to an integer. */
+#define OBJ_INT(x)    (int)get_ul(x)
+
+/* Conversions of sxprs to their values.
+ * No checking is done.
+ */
+#define OBJ_STRING(x)  ((ObjString*)get_ptr(x))
+#define OBJ_CONS(x)    ((ObjCons*)get_ptr(x))
+#define OBJ_ATOM(x)    ((ObjAtom*)get_ptr(x))
+#define OBJ_SET(x)     ((ObjSet*)get_ptr(x))
+#define CAR(x)         (OBJ_CONS(x)->car)
+#define CDR(x)         (OBJ_CONS(x)->cdr)
+
+#define CAAR(x)        (CAR(CAR(x)))
+#define CADR(x)        (CAR(CDR(x)))
+#define CDAR(x)        (CDR(CAR(x)))
+#define CDDR(x)        (CDR(CDR(x)))
+
+/** Checked version of CAR
+ *
+ * @param x sxpr
+ * @return CAR if a cons, x otherwise
+ */
+static inline Sxpr car(Sxpr x){
+    return (CONSP(x) ? CAR(x) : x);
+}
+
+/** Checked version of CDR.
+ *
+ * @param x sxpr
+ * @return CDR if a cons, null otherwise
+ */
+static inline Sxpr cdr(Sxpr x){
+    return (CONSP(x) ? CDR(x) : ONULL);
+}
+
+typedef int ObjPrintFn(IOStream *io, Sxpr obj, unsigned flags);
+typedef int ObjEqualFn(Sxpr obj, Sxpr other);
+typedef void ObjFreeFn(Sxpr obj);
+typedef Sxpr ObjCopyFn(Sxpr obj);
+
+/** An sxpr type definition. */
+typedef struct SxprType {
+    TypeCode type;
+    char *name;
+    int pointer;
+    ObjPrintFn *print;
+    ObjEqualFn *equal;
+    ObjFreeFn *free;
+    ObjCopyFn *copy;
+} SxprType;
+
+
+extern int def_sxpr_type(SxprType *tydef);
+extern SxprType *get_sxpr_type(int ty);
+
+/** Free the pointer in an sxpr.
+ *
+ * @param x sxpr containing a pointer
+ */
+static inline void hfree(Sxpr x){
+    deallocate(get_ptr(x));
+}
+
+extern int objprint(IOStream *io, Sxpr x, unsigned flags);
+extern int objequal(Sxpr x, Sxpr y);
+extern void objfree(Sxpr x);
+extern Sxpr objcopy(Sxpr x);
+
+extern void cons_free_cells(Sxpr obj);
+extern Sxpr intern(char *s);
+
+extern Sxpr assoc(Sxpr k, Sxpr l);
+extern Sxpr assocq(Sxpr k, Sxpr l);
+extern Sxpr acons(Sxpr k, Sxpr v, Sxpr l);
+extern Sxpr nrev(Sxpr l);
+extern Sxpr cons_member(Sxpr l, Sxpr x);
+extern Sxpr cons_member_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v);
+extern int cons_subset(Sxpr s, Sxpr t);
+extern int cons_set_equal(Sxpr s, Sxpr t);
+
+#ifdef USE_GC
+extern Sxpr cons_remove(Sxpr l, Sxpr x);
+extern Sxpr cons_remove_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v);
+#endif
+
+extern Sxpr atom_new(char *name);
+extern char * atom_name(Sxpr obj);
+extern int atom_length(Sxpr obj);
+
+extern Sxpr string_new(char *s);
+extern Sxpr string_new_n(char *s, int n);
+extern char * string_string(Sxpr obj);
+extern int string_length(Sxpr obj);
+
+extern Sxpr cons_new(Sxpr car, Sxpr cdr);
+extern int cons_push(Sxpr *list, Sxpr elt);
+extern int cons_length(Sxpr obj);
+
+Sxpr sxpr_name(Sxpr obj);
+int sxpr_is(Sxpr obj, char *s);
+int sxpr_elementp(Sxpr obj, Sxpr name);
+Sxpr sxpr_attributes(Sxpr obj);
+Sxpr sxpr_attribute(Sxpr obj, Sxpr key, Sxpr def);
+Sxpr sxpr_children(Sxpr obj);
+Sxpr sxpr_child(Sxpr obj, Sxpr name, Sxpr def);
+Sxpr sxpr_childN(Sxpr obj, int n, Sxpr def);
+Sxpr sxpr_child0(Sxpr obj, Sxpr def);
+Sxpr sxpr_child_value(Sxpr obj, Sxpr name, Sxpr def);
+
+/** Create a new atom.
+ *
+ * @param s atom name
+ * @return new atom
+ */
+static inline Sxpr mkatom(char *s){
+    return atom_new(s);
+}
+
+/** Create a new string sxpr.
+ *
+ * @param s string bytes (copied)
+ * @return new string
+ */
+static inline Sxpr mkstring(char *s){
+    return string_new(s);
+}
+
+/** Create an integer sxpr.
+ *
+ * @param i value
+ * @return sxpr
+ */
+static inline Sxpr mkint(int i){
+    return OBJI(T_UINT, i);
+}
+
+/** Create a boolean sxpr.
+ *
+ * @param b value
+ * @return sxpr
+ */
+static inline Sxpr mkbool(int b){
+    return OBJI(T_BOOL, (b ? 1 : 0));
+}
+
+/* Constants used in parsing and printing. */
+#define k_list_open    "("
+#define c_list_open    '('
+#define k_list_close   ")"
+#define c_list_close   ')'
+#define k_true         "true"
+#define k_false        "false"
+
+#define c_escape       '\\'
+#define c_single_quote '\''
+#define c_double_quote '"'
+#define c_string_open  c_double_quote
+#define c_string_close c_double_quote
+
+#define c_data_open    '<'
+#define c_data_quote   '<'
+#define c_data_count   '*'
+//#define c_data_open    '['
+//#define c_data_close   ']'
+//#define c_binary       '*'
+
+#define c_var          '$'
+#define c_eval         '!'
+#define c_concat_open  '{'
+#define c_concat_close '}'
+
+#endif /* ! _XUTIL_SXPR_H_ */
diff --git a/tools/vnet/libxutil/sxpr_parser.c b/tools/vnet/libxutil/sxpr_parser.c
new file mode 100644 (file)
index 0000000..f93d350
--- /dev/null
@@ -0,0 +1,991 @@
+/*
+ * Copyright (C) 2001 - 2005 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or  (at your option) any later version. This library is 
+ * distributed in the  hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#ifdef __KERNEL__
+#  include <linux/config.h>
+#  include <linux/module.h>
+#  include <linux/kernel.h>
+#  include <linux/string.h>
+#  include <linux/errno.h>
+#else
+#  include <stdlib.h>
+#  include <errno.h>
+#endif
+
+#include "sys_net.h"
+
+#include "iostream.h"
+#include "lexis.h"
+#include "sxpr_parser.h"
+#include "sys_string.h"
+#include "enum.h"
+
+/** @file
+ * Sxpr parsing.
+ *
+ * So that the parser does not leak memory, all sxprs constructed by
+ * the parser must be freed on error.  On successful parse the sxpr
+ * returned becomes the responsibility of the caller.
+ *
+ * @author Mike Wray <mike.wray@hpl.hp.com>
+ */
+
+#ifdef DEBUG
+#define dprintf(fmt, args...) IOStream_print(iostdout, "[DEBUG] %s" fmt, __FUNCTION__, ##args)
+#else
+#define dprintf(fmt, args...) do{ }while(0)
+#endif
+
+#undef printf
+#define printf(fmt, args...)   IOStream_print(iostdout, fmt, ##args)
+
+static int state_start(Parser *p, char c);
+static int begin_start(Parser *p, char c);
+
+#if 0
+/** Print a parse error.
+ *
+ * @param in parser
+ * @param msg format followed by printf arguments
+ */
+static void eprintf(Parser *in, char *msg, ...){
+    va_list args;
+    if(in->error_out){
+        va_start(args, msg);
+        IOStream_vprint(in->error_out, msg, args);
+        va_end(args);
+    }
+}
+
+/** Print a parse warning.
+ *
+ * @param in parser
+ * @param msg format followed by printf arguments
+ */
+static void wprintf(Parser *in, char *msg, ...){
+    va_list args;
+    if(in->error_out){
+        va_start(args, msg);
+        IOStream_vprint(in->error_out, msg, args);
+        va_end(args);
+    }
+}
+#endif
+
+
+/*============================================================================*/
+
+/** Record defining the message for a parse error. */
+typedef struct {
+    ParseErrorId id;
+    char *message;
+} ParseError;
+
+/** Format for printing parse error messages. */
+#define PARSE_ERR_FMT "parse error> line %3d, column %2d: %s"
+
+/** Message catalog for the parse error codes. */
+static ParseError catalog[] = {
+    { PARSE_ERR_UNSPECIFIED,            "unspecified error" },
+    { PARSE_ERR_NOMEM,                  "out of memory" },
+    { PARSE_ERR_UNEXPECTED_EOF,         "unexpected end of input" },
+    { PARSE_ERR_TOKEN_TOO_LONG,         "token too long" },
+    { PARSE_ERR_INVALID_SYNTAX,         "syntax error" },
+    { PARSE_ERR_INVALID_ESCAPE,         "invalid escape" },
+    { 0, NULL }
+};
+
+/** Number of entries in the message catalog. */
+const static int catalog_n = sizeof(catalog)/sizeof(ParseError);
+
+/** Set the parser error stream.
+ * Parse errors are reported on the the error stream if it is non-null.
+ * 
+ * @param z parser
+ * @param error_out error stream
+ */
+void Parser_set_error_stream(Parser *z, IOStream *error_out){
+    z->error_out = error_out;
+}
+
+/** Get the parser error message for an error code.
+ *
+ * @param id error code
+ * @return error message (empty string if the code is unknown)
+ */
+static char *get_message(ParseErrorId id){
+    int i;
+    for(i = 0; i < catalog_n; i++){
+        if(id == catalog[i].id){
+            return catalog[i].message;
+        }
+    }
+    return "";
+}
+
+#if 0
+/** Get the line number.
+ *
+ * @param in parser
+ */
+static int get_line(Parser *in){
+    return in->line_no;
+}
+
+/** Get the column number.
+ *
+ * @param in parser
+ */
+static int get_column(Parser *in){
+    return in->char_no;
+}
+#endif
+
+/** Get the line number the current token started on.
+ *
+ * @param in parser
+ */
+static int get_tok_line(Parser *in){
+    return in->tok_begin_line;
+}
+
+/** Get the column number the current token started on.
+ *
+ * @param in parser
+ */
+static int get_tok_column(Parser *in){
+    return in->tok_begin_char;
+}
+
+/** Return the current token.
+ * The return value points at the internal buffer, so
+ * it must not be modified (or freed). Use copy_token() if you need a copy.
+ *
+ * @param p parser
+ * @return token
+ */
+char *peek_token(Parser *p){
+    return p->tok;
+}
+
+int token_len(Parser *p){
+    return p->tok_end - p->tok;
+}
+
+/** Return a copy of the current token.
+ * The returned value should be freed when finished with.
+ *
+ * @param p parser
+ * @return copy of token
+ */
+char *copy_token(Parser *p){
+    int n = token_len(p);
+    char *buf = allocate(n + 1);
+    if(buf){
+        memcpy(buf, peek_token(p), n);
+        buf[n] = '\0';
+    }
+    return buf;
+}
+
+void new_token(Parser *p){
+    memset(p->buf, 0, p->buf_end - p->buf);
+    p->tok = p->buf;
+    p->tok_end = p->tok;
+    p->tok_begin_line = p->line_no;
+    p->tok_begin_char = p->char_no;
+}
+
+/** Report a parse error.
+ * Does nothing if the error stream is null or there is no error.
+ *
+ * @param in parser
+ */
+static void report_error(Parser *in){
+    if(in->error_out && in->err){
+        char *msg = get_message(in->err);
+        char *tok = peek_token(in);
+        IOStream_print(in->error_out, PARSE_ERR_FMT,
+                       get_tok_line(in), get_tok_column(in), msg);
+        if(tok && tok[0]){
+            IOStream_print(in->error_out, " '%s'", tok);
+        }
+        IOStream_print(in->error_out, "\n");
+    }
+}
+
+/** Get the error message for the current parse error code.
+ * Does nothing if there is no error.
+ *
+ * @param in parser
+ * @param buf where to place the message
+ * @param n maximum number of characters to place in buf
+ * @return current error code (zero for no error)
+ */
+int Parser_error_message(Parser *in, char *buf, int n){
+    if(in->err){
+        char *msg = get_message(in->err);
+        snprintf(buf, n, PARSE_ERR_FMT, get_tok_line(in),
+                 get_tok_column(in), msg);
+    }
+    return in->err;
+}
+
+/** Flag a parse error. All subsequent reads will fail.
+ * Does not change the parser error code if it is already set.
+ *
+ * @param in parser
+ * @param id error code
+ */
+int Parser_error_id(Parser *in, ParseErrorId id){
+    if(!in->err){
+        in->err = id;
+        report_error(in);
+    }
+    return -EINVAL;
+}
+
+/** Flag an unspecified parse error.
+ *
+ * @param in parser
+ */
+int Parser_error(Parser *in){
+    return Parser_error_id(in, PARSE_ERR_INVALID_SYNTAX);
+}
+
+/** Test if the parser's error flag is set.
+ *
+ * @param in parser
+ * @return 1 if set, 0 otherwise
+ */
+int Parser_has_error(Parser *in){
+    return (in->err > 0);
+}
+
+/** Test if the parser is at end of input.
+ *
+ * @param in parser
+ * @return 1 if at EOF, 0 otherwise
+ */
+int Parser_at_eof(Parser *p){
+    return p->eof;
+}
+
+void ParserState_free(ParserState *z){
+    if(!z) return;
+    objfree(z->val);
+    deallocate(z);
+}
+
+int ParserState_new(ParserStateFn *fn, char *name,
+                    ParserState *parent, ParserState **val){
+    int err = -ENOMEM;
+    ParserState *z;
+    z = ALLOCATE(ParserState);
+    if(!z) goto exit;
+    z->name = name;
+    z->fn = fn;
+    z->parent = parent;
+    z->val = ONULL;
+    err = 0;
+  exit:
+    *val = (err ? NULL : z);
+    return err;
+}
+
+void Parser_pop(Parser *p){
+    ParserState *s = p->state;
+    if(!s) return;
+    p->state = s->parent;
+    if (p->start_state == s) {
+        p->start_state = NULL;
+    }
+    ParserState_free(s);
+}
+
+/** Free a parser.
+ * No-op if the parser is null.
+ *
+ * @param z parser 
+ */
+void Parser_free(Parser *z){
+    if(!z) return;
+    // Hmmm. Need to free states, but careful about double free of values.
+    while(z->state){
+        objfree(z->state->val);
+        Parser_pop(z);
+    }
+    if(z->buf) deallocate(z->buf);
+    objfree(z->val);
+    z->val = ONONE;
+    deallocate(z);
+}
+
+int Parser_push(Parser *p, ParserStateFn *fn, char *name){
+    return ParserState_new(fn, name, p->state, &p->state);
+}
+        
+int Parser_return(Parser *p){
+    int err = 0;
+    Sxpr val = ONONE;
+    if(!p->state){
+        err = -EINVAL;
+        goto exit;
+    }
+    val = p->state->val;
+    p->state->val = ONONE;
+    Parser_pop(p);
+    if(p->state){
+        err = cons_push(&p->state->val, val);
+    } else {
+        val = nrev(val);
+        p->val = val;
+    }
+  exit:
+    if(err){
+        objfree(val);
+    }
+    return err;
+}
+
+/** Reset the fields of a parser to initial values.
+ *
+ * @param z parser
+ */
+static void reset(Parser *z){
+    // leave flags
+    // leave error_out
+    while(z->state){
+        Parser_pop(z);
+    }
+    z->val = ONONE;
+    z->eof = 0;
+    z->err = 0;
+    z->line_no = 1;
+    z->char_no = 0;
+    memset(z->buf, 0, z->buf_end - z->buf);
+    z->tok = z->buf;
+    z->tok_end = z->tok;
+    z->tok_begin_line = 0;
+    z->tok_begin_char = 0;
+    z->start_state = NULL;
+}
+
+/** Create a new parser. The error stream defaults to null.
+ */
+Parser * Parser_new(void){
+    Parser *z = ALLOCATE(Parser);
+    int n = PARSER_BUF_SIZE;
+    int err = -ENOMEM;
+  
+    if(!z) goto exit;
+    z->buf = allocate(n);
+    if(!z->buf) goto exit;
+    err = 0;
+    z->buf_end = z->buf + n;
+    z->begin = begin_start;
+    reset(z);
+  exit:
+    if(err){
+        Parser_free(z);
+        z = NULL;
+    }
+    return z;
+}
+
+/** Get the next character.
+ * Records the character read in the parser,
+ * and sets the line and character counts.
+ *
+ * @param p parser
+ * @return error flag: 0 on success, non-zero on error
+ */
+static int input_char(Parser *p, char c){
+    int err = 0;
+    if(c=='\n'){
+        p->line_no++;
+        p->char_no = 0;
+    } else {
+        p->char_no++;
+    }
+    return err;
+}
+
+int save_char(Parser *p, char c){
+    int err = 0;
+    if(p->tok_end >= p->buf_end){
+        int buf_n = (p->buf_end - p->buf) + PARSER_BUF_INCREMENT;
+        char *buf = allocate(buf_n);
+        if(!buf){
+            err = -ENOMEM;
+            goto exit;
+        }
+        memcpy(buf, p->buf, p->tok_end - p->buf);
+        p->buf_end = buf + buf_n;
+        p->tok     = buf + (p->tok     - p->buf);
+        p->tok_end = buf + (p->tok_end - p->buf);
+        deallocate(p->buf);
+        p->buf = buf;
+    }
+    *p->tok_end++ = c;
+  exit:
+    return err;
+}
+
+/** Determine if a character is a separator.
+ *
+ * @param p parser
+ * @param c character to test
+ * @return 1 if a separator, 0 otherwise
+ */
+static int is_separator(Parser *p, char c){
+    return in_sep_class(c);
+}
+
+int Parser_set_value(Parser *p, Sxpr obj){
+    int err = 0;
+    if(NOMEMP(obj)){
+        err = -ENOMEM;
+    } else {
+        p->state->val = obj;
+    }
+    return err;
+}
+    
+int Parser_intern(Parser *p){
+    Sxpr obj = intern(peek_token(p));
+    return Parser_set_value(p, obj);
+}
+
+int Parser_atom(Parser *p){
+    Sxpr obj = atom_new(peek_token(p));
+    return Parser_set_value(p, obj);
+}
+
+int Parser_string(Parser *p){
+    Sxpr obj = string_new_n(peek_token(p), token_len(p));
+    return Parser_set_value(p, obj);
+}
+
+int Parser_data(Parser *p){
+    Sxpr obj = string_new_n(peek_token(p), token_len(p));
+    return Parser_set_value(p, obj);
+}
+
+int Parser_uint(Parser *p){
+    unsigned int x = htonl(*(unsigned int *)peek_token(p));
+    return Parser_set_value(p, OINT(x));
+}
+
+static int get_escape(char c, char *d){
+    int err = 0;
+    switch(c){
+    case 'a':            *d = '\a'; break;
+    case 'b':            *d = '\b'; break;
+    case 'f':            *d = '\f'; break;
+    case 'n':            *d = '\n'; break;
+    case 'r':            *d = '\r'; break;
+    case 't':            *d = '\t'; break;
+    case 'v':            *d = '\v'; break;
+    case c_escape:       *d = c_escape; break;
+    case c_single_quote: *d = c_single_quote; break;
+    case c_double_quote: *d = c_double_quote; break;
+    default:
+        err = -EINVAL;
+    }
+    return err;
+}
+
+int Parser_ready(Parser *p){
+    return CONSP(p->val) || (p->start_state && CONSP(p->start_state->val));
+}
+
+Sxpr Parser_get_val(Parser *p){
+    Sxpr v = ONONE;
+    if(CONSP(p->val)){
+    } else if (p->start_state && CONSP(p->start_state->val)){
+        p->val = p->start_state->val;
+        p->val = nrev(p->val);
+        p->start_state->val = ONULL;
+    }  else {
+        goto exit;
+    }
+    Sxpr w = p->val;
+    v = CAR(w);
+    p->val = CDR(w);
+    hfree(w);
+  exit:
+    return v;
+}
+
+Sxpr Parser_get_all(Parser *p){
+    Sxpr v = ONULL;
+    if(CONSP(p->val)){
+        v = p->val;
+        p->val = ONONE;
+    } else if(p->start_state && CONSP(p->start_state->val)){
+        v = p->start_state->val;
+        p->start_state->val = ONULL;
+        v = nrev(v);
+    }
+    return v;
+}
+
+static int state_comment(Parser *p, char c){
+    int err = 0;
+    if(c == '\n' || Parser_at_eof(p)){
+        Parser_pop(p);
+    } else {
+        err = input_char(p, c);
+    }
+    return err;
+}
+
+static int begin_comment(Parser *p, char c){
+    int err = 0;
+    err = Parser_push(p, state_comment, "comment");
+    if(err) goto exit;
+    err = input_char(p, c);
+  exit:
+    return err;
+}
+
+static int end_string(Parser *p){
+    int err = 0;
+    err = Parser_string(p);
+    if(err) goto exit;
+    err = Parser_return(p);
+  exit:
+    return err;
+}
+
+static int octaldone(Parser *p){
+    int err = 0;
+    char d = (char)(p->state->ival & 0xff);
+    Parser_pop(p);
+    err = Parser_input_char(p, d);
+    return err;
+}
+
+static int octaldigit(Parser *p, int d){
+    int err = 0;
+    p->state->ival *= 8;
+    p->state->ival += d; 
+    p->state->count++;
+    if(err) goto exit;
+    if(p->state->ival < 0 || p->state->ival > 0xff){
+        err = Parser_error(p);
+        goto exit;
+    }
+    if(p->state->count == 3){
+        err = octaldone(p);
+    }
+  exit:
+    return err;
+}
+
+static int state_octal(Parser *p, char c){
+    int err = 0;
+    if(Parser_at_eof(p)){
+        err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
+        goto exit;
+    } else if('0' <= c && c <= '7'){
+        err = octaldigit(p, c - '0');
+    } else {
+        err = octaldone(p);
+        if(err) goto exit;
+        Parser_input_char(p, c);
+    }
+  exit:
+    return err;
+}
+
+static int hexdone(Parser *p){
+    int err = 0;
+    char d = (char)(p->state->ival & 0xff);
+    Parser_pop(p);
+    err = Parser_input_char(p, d);
+    return err;
+}
+    
+static int hexdigit(Parser *p, int d){
+    int err = 0;
+    p->state->ival *= 16;
+    p->state->ival += d; 
+    p->state->count++;
+    if(err) goto exit;
+    if(p->state->ival < 0 || p->state->ival > 0xff){
+        err = Parser_error(p);
+        goto exit;
+    }
+    if(p->state->count == 2){
+        err = hexdone(p);
+    }
+  exit:
+    return err;
+}
+    
+static int state_hex(Parser *p, char c){
+    int err = 0;
+    if(Parser_at_eof(p)){
+        err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
+        goto exit;
+    } else if('0' <= c && c <= '9'){
+        err = hexdigit(p, c - '0');
+    } else if('A' <= c && c <= 'F'){
+        err = hexdigit(p, c - 'A' + 10);
+    } else if('a' <= c && c <= 'f'){
+        err = hexdigit(p, c - 'a' + 10);
+    } else if(p->state->count){
+        err = hexdone(p);
+        if(err) goto exit;
+        Parser_input_char(p, c);
+    }
+  exit:
+    return err;
+}
+
+static int state_escape(Parser *p, char c){
+    int err = 0;
+    char d;
+    if(Parser_at_eof(p)){
+        err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
+        goto exit;
+    }
+    if(get_escape(c, &d) == 0){
+        err = save_char(p, d);
+        if(err) goto exit;
+        Parser_pop(p);
+    } else if(c == 'x'){
+        p->state->fn = state_hex;
+        p->state->ival = 0;
+        p->state->count = 0;
+    } else {
+        p->state->fn = state_octal;
+        p->state->ival = 0;
+        p->state->count = 0;
+        err = Parser_input_char(p, c);
+    }
+  exit:
+    return err;
+}
+
+static int state_string(Parser *p, char c){
+    int err = 0;
+    if(Parser_at_eof(p)){
+        err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
+    } else if(c == p->state->delim){
+        err = end_string(p);
+    } else if(c == '\\'){
+        err = Parser_push(p, state_escape, "escape");
+    } else {
+        err = save_char(p, c);
+    }
+    return err;
+}
+
+static int begin_string(Parser *p, char c){
+    int err = 0;
+    err = Parser_push(p, state_string, "string");
+    if(err) goto exit;
+    new_token(p);
+    p->state->delim = c;
+  exit:
+    return err;
+}
+
+static int end_atom(Parser *p){
+    int err = 0;
+    err = Parser_atom(p);
+    if(err) goto exit;
+    err = Parser_return(p);
+  exit:
+    return err;
+}
+
+static int state_atom(Parser *p, char c){
+    int err = 0;
+    if(Parser_at_eof(p)){
+        err = end_atom(p);
+    } else if(is_separator(p, c) ||
+              in_space_class(c) ||
+              in_comment_class(c)){
+        err = end_atom(p);
+        if(err) goto exit;
+        err = Parser_input_char(p, c);
+    } else {
+        err = save_char(p, c);
+    }
+  exit:
+    return err;
+}
+
+static int begin_atom(Parser *p, char c){
+    int err = 0;
+    err = Parser_push(p, state_atom, "atom");
+    if(err) goto exit;
+    new_token(p);
+    err = save_char(p, c);
+  exit:
+    return err;
+}
+
+static int end_data(Parser *p){
+    int err = 0;
+    err = Parser_data(p);
+    if(err) goto exit;
+    err = Parser_return(p);
+  exit:
+    return err;
+}
+
+static int counted_data(Parser *p, char c){
+    int err = 0;
+    err = save_char(p, c);
+    if(err) goto exit;
+    if(token_len(p) == p->state->count){
+        err = end_data(p);
+    }
+  exit:
+    return err;
+}
+
+static int counted_data_count(Parser *p, char c){
+    int err = 0;
+    if(c == p->state->delim){
+        new_token(p);
+        p->state->count = p->state->ival;
+        p->state->fn = counted_data;
+    } else if('0' <= c && c <= '9'){
+        p->state->ival *= 10;
+        p->state->ival += c - '0';
+    } else {
+        err = -EINVAL;
+    }
+    return err;
+}
+
+static int quoted_data(Parser *p, char c){
+    int err = 0;
+    int count = p->state->count;
+    err = save_char(p, c);
+    if(err) goto exit;
+    // Check that buf is longer than delim and
+    // ends with delim. If so, trim delim off and return.
+    if((token_len(p) >= count) &&
+       !memcmp(p->tok_end - count, p->buf, count)){
+        p->tok_end -= count;
+        end_data(p);
+    }
+  exit:
+    return err;
+}
+
+static int quoted_data_delim(Parser *p, char c){
+    // Saves the delim in the token buffer.
+    int err = 0;
+    err = save_char(p, c);
+    if(err) goto exit;
+    if(c == p->state->delim){
+        p->state->fn = quoted_data;
+        p->state->count = token_len(p);
+        // Advance the token pointer past the delim.
+        p->tok = p->tok_end;
+    }
+  exit:
+    return err;
+}
+
+static int state_data(Parser *p, char c){
+    // Quoted data:
+    // <<delim< anything not containing delimiter<delim<
+    // Where 'delim' is anything not containing '<'.
+    // Counted data:
+    // <*nnn..* N bytes
+    // Where nnn... is N in decimal (
+    int err = 0;
+    switch(c){
+    case c_data_count:
+        p->state->delim = c;
+        p->state->fn = counted_data_count;
+        p->state->ival = 0;
+        new_token(p);
+        break;
+    case c_data_quote:
+        p->state->delim = c;
+        p->state->fn = quoted_data_delim;
+        new_token(p);
+        err = save_char(p, c);
+        break;
+    default:
+        err = Parser_error(p);
+        break;
+    }
+    return err;
+}
+
+static int begin_data(Parser *p, char c){
+    int err = 0;
+    err = Parser_push(p, state_data, "data");
+    if(err) goto exit;
+    new_token(p);
+  exit:
+    return err;
+}
+
+static int state_list(Parser *p, char c){
+    int err = 0;
+    dprintf(">\n");
+    if(Parser_at_eof(p)){
+        err = Parser_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
+    } else if(c == c_list_close){
+        p->state->val = nrev(p->state->val);
+        err = Parser_return(p);
+    } else {
+        err = state_start(p, c);
+    }
+    dprintf("< err=%d\n", err);
+    return err;
+    
+}
+
+static int begin_list(Parser *p, char c){
+    return Parser_push(p, state_list, "list");
+}
+
+static int state_start(Parser *p, char c){
+    int err = 0;
+    dprintf(">\n");
+    if(Parser_at_eof(p)){
+        err = Parser_return(p);
+    } else if(in_space_class(c)){
+        //skip
+    } else if(in_comment_class(c)){
+        begin_comment(p, c);
+    } else if(c == c_list_open){
+        begin_list(p, c);
+    } else if(c == c_list_close){
+        err = Parser_error(p);
+    } else if(in_string_quote_class(c)){
+        begin_string(p, c);
+    } else if(c == c_data_open){
+        begin_data(p, c);
+    } else if(in_printable_class(c)){
+        begin_atom(p, c);
+    } else if(c == 0x04){
+        //ctrl-D, EOT: end-of-text.
+        Parser_input_eof(p);
+    } else {
+        err = Parser_error(p);
+    }
+    dprintf("< err=%d\n", err);
+    return err;
+}
+
+int begin_start(Parser *p, char c){
+    int err = 0;
+    dprintf(">\n");
+    err = Parser_push(p, state_start, "start");
+    if(err) goto exit;
+    p->start_state = p->state;
+  exit:
+    dprintf("< err=%d\n", err);
+    return err;
+}
+
+int Parser_input_char(Parser *p, char c){
+    int err = 0;
+    if(Parser_at_eof(p)){
+        //skip;
+    } else {
+        input_char(p, c);
+    }
+    if(!p->state){
+        err = p->begin(p, c);
+        if(err) goto exit;
+    }
+    err = p->state->fn(p, c);
+  exit:
+    return err;
+}
+
+int Parser_input_eof(Parser *p){
+    int err = 0;
+    p->eof = 1;
+    err = Parser_input_char(p, IOSTREAM_EOF);
+    return err;
+}
+
+int Parser_input(Parser *p, char *buf, int buf_n){
+    int err = 0;
+    int i = 0;
+    dprintf("> |%s|\n", buf);
+    if(buf_n <= 0){
+        err = Parser_input_eof(p);
+        goto exit;
+    }
+    for(i = 0; i < buf_n; i++){
+        err = Parser_input_char(p, buf[i]);
+        if(err) goto exit;
+    }
+  exit:
+    err = (err < 0 ? err : buf_n);
+    dprintf("< err=%d\n", err);
+    return err;
+}
+
+#ifdef SXPR_PARSER_MAIN
+/* Stuff for standalone testing. */
+
+#include "file_stream.h"
+//#include "string_stream.h"
+
+/** Main program for testing.
+ * Parses input and prints it.
+ *
+ * @param argc number of arguments
+ * @param argv arguments
+ * @return error code
+ */
+int main(int argc, char *argv[]){
+    Parser *pin;
+    int err = 0;
+    char buf[1024];
+    int k;
+    Sxpr obj;
+    int i = 0;
+
+    pin = Parser_new();
+    Parser_set_error_stream(pin, iostdout);
+    dprintf("> parse...\n");
+    while(1){
+        k = fread(buf, 1, 100, stdin);
+        if(k>=0){
+            buf[k+1] = '\0';
+        }
+        err = Parser_input(pin, buf, k);
+        while(Parser_ready(pin)){
+            obj = Parser_get_val(pin);
+            printf("obj %d\n", i++);
+            objprint(iostdout, obj, 0); printf("\n");
+        }
+        if(k <= 0) break;
+    }
+    dprintf("> err=%d\n", err);
+    return 0;
+}
+#endif
diff --git a/tools/vnet/libxutil/sxpr_parser.h b/tools/vnet/libxutil/sxpr_parser.h
new file mode 100644 (file)
index 0000000..591ed95
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2001 - 2005 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or  (at your option) any later version. This library is 
+ * distributed in the  hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#ifndef _XUTIL_SXPR_PARSER_H_
+#define _XUTIL_SXPR_PARSER_H_
+
+#include "sxpr.h"
+#include "iostream.h"
+
+/** @file
+ * Sxpr parsing definitions.
+ */
+
+/** Initial size of a parser input buffer.
+ */
+#define PARSER_BUF_SIZE 512
+
+/** Input buffer size increment (when it's full).
+ */
+#define PARSER_BUF_INCREMENT 512
+
+struct Parser;
+typedef int ParserStateFn(struct Parser *, char c);
+
+typedef struct ParserState {
+    struct ParserState *parent;
+    Sxpr val;
+    int ival;
+    int count;
+    char delim;
+    ParserStateFn *fn;
+    char *name;
+} ParserState;
+
+typedef struct Parser {
+    /** Initial state function. */
+    ParserStateFn *begin;
+    /** Parse value. */
+    Sxpr val;
+    /** Error reporting stream (null for no reports). */
+    IOStream *error_out;
+    /** End-of-file flag, */
+    int eof;
+    /** Error flag. Non-zero if there has been a read error. */
+    int err;
+    /** Line number on input (from 1). */
+    int line_no;
+    /** Column number of input (reset on new line). */
+    int char_no;
+    /** Buffer for reading tokens. */
+    char *buf;
+    char *buf_end;
+    char *tok;
+    char *tok_end;
+    /** Line the last token started on. */
+    int tok_begin_line;
+    /** Character number the last token started on. */
+    int tok_begin_char;
+    /** Parsing flags. */
+    int flags;
+    ParserState *state;
+    ParserState *start_state;
+} Parser;
+
+/** Parser error codes. */
+typedef enum {
+    PARSE_ERR_NONE=0,
+    PARSE_ERR_UNSPECIFIED,
+    PARSE_ERR_NOMEM,
+    PARSE_ERR_UNEXPECTED_EOF,
+    PARSE_ERR_TOKEN_TOO_LONG,
+    PARSE_ERR_INVALID_SYNTAX,
+    PARSE_ERR_INVALID_ESCAPE,
+} ParseErrorId;
+
+
+/** Parser flags. */
+//enum {
+//};
+
+/** Raise some parser flags.
+ *
+ * @param in parser
+ * @param flags flags mask
+ */
+inline static void Parser_flags_raise(Parser *in, int flags){
+    in->flags |= flags;
+}
+
+/** Lower some parser flags.
+ *
+ * @param in parser
+ * @param flags flags mask
+ */
+inline static void Parser_flags_lower(Parser *in, int flags){
+    in->flags &= ~flags;
+}
+
+/** Clear all parser flags.
+ *
+ * @param in parser
+ */
+inline static void Parser_flags_clear(Parser *in){
+    in->flags = 0;
+}
+
+extern void Parser_free(Parser *z);
+extern Parser * Parser_new(void);
+extern int Parser_input(Parser *p, char *buf, int buf_n);
+extern int Parser_input_eof(Parser *p);
+extern int Parser_input_char(Parser *p, char c);
+extern void Parser_set_error_stream(Parser *z, IOStream *error_out);
+
+extern int Parser_error_message(Parser *in, char *buf, int n);
+extern int Parser_has_error(Parser *in);
+extern int Parser_at_eof(Parser *in);
+
+extern int Parser_ready(Parser *p);
+extern Sxpr Parser_get_val(Parser *p);
+extern Sxpr Parser_get_all(Parser *p);
+
+/* Internal parser api. */
+void Parser_pop(Parser *p);
+int Parser_push(Parser *p, ParserStateFn *fn, char *name);
+int Parser_return(Parser *p);
+int Parser_at_eof(Parser *p);
+int Parser_error(Parser *in);
+int Parser_set_value(Parser *p, Sxpr val);
+int Parser_intern(Parser *p);
+int Parser_string(Parser *p);
+int Parser_data(Parser *p);
+int Parser_uint(Parser *p);
+
+char *peek_token(Parser *p);
+char *copy_token(Parser *p);
+void new_token(Parser *p);
+int save_char(Parser *p, char c);
+int token_len(Parser *p);
+
+#endif /* ! _XUTIL_SXPR_PARSER_H_ */
diff --git a/tools/vnet/libxutil/sys_net.c b/tools/vnet/libxutil/sys_net.c
new file mode 100644 (file)
index 0000000..4143601
--- /dev/null
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or  (at your option) any later version. This library is 
+ * distributed in the  hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include "sys_net.h"
+#include "sys_string.h"
+
+#ifdef __KERNEL__
+#  include <linux/errno.h>
+#else
+#  include <errno.h>
+#endif
+
+/** @file
+ * All network data are kept in network order and only converted to
+ * host order for display. Network data includes IP addresses, port numbers and
+ * network masks.
+ */
+
+/** Maximum value for a port. */
+#define PORT_MAX 0xffff
+
+/** Convert a number of bits to a network mask
+ * for IP addresses. The number of bits must
+ * be in the range 1-31.
+ *
+ * @param n number of bits to set in the mask
+ * @return value with n high bits set (in network order)
+ */
+unsigned long bits_to_mask(int n){
+    unsigned long mask = (n ? (1 << 31) : 0);
+    int i;
+    for(i=1; i<n; i++){
+        mask |= (mask >> 1);
+    }
+    return htonl(mask);
+}
+
+/** Convert a network mask to a number of bits.
+ *
+ * @param mask network mask in network order
+ * @return number of bits in mask
+ */
+int mask_to_bits(unsigned long mask){
+    // Start with n set to the number of bits in the mask. Then reduce n by
+    // the number of low zero bits in the mask.
+    int n = 32;
+    for(mask = ntohl(mask);
+        (mask & 1)==0 && n>0;
+        mask >>= 1){
+        n--;
+    }
+    return n;
+}
+
+/** Get the index of the first occurrence of a character in a string.
+ * Stops at end of string or after n characters.
+ *
+ * @param s input string
+ * @param n maximum number of charactes to search
+ * @param c character to look for
+ * @return index of first occurrence, -1 if not found
+ */
+inline static int indexof(const char *s, int n, char c){
+    int i;
+    for(i=0; i<n && *s; i++, s++){
+        if(*s == c) return i;
+    }
+    return -1;
+}
+
+/** Convert an IPv4 address in dot notation into an unsigned long (in network order).
+ *
+ * @param s input string
+ * @param address where to put the address
+ * @return 0 on success, negative on error
+ */
+int get_inet_addr(const char *s, unsigned long *address){
+    // Number of bits in a byte.
+    const int BYTE_BITS = 8;
+    // Number of bytes in a word.
+    const int WORD_BYTES = 4;
+    // Max value for a component of an address.
+    const int ADDR_MAX  = 255;
+    // Separator for components of an address.
+    const char dot = '.';
+
+    int n;
+    unsigned long addr = 0;
+    unsigned long v;
+    int i;
+    int err = -EINVAL;
+    // Bit shift for the current byte.
+    int shift = BYTE_BITS * (WORD_BYTES - 1);
+    char buf[64];
+
+    n = strlen(s);
+    if(n >= sizeof(buf)){
+        goto exit;
+    }
+    for(i=0; i < WORD_BYTES; i++){
+        int idx = indexof(s, n, dot);
+        idx = (idx < 0 ? strlen(s) : idx);
+        strncpy(buf, s, idx); buf[idx]='\0';
+        if(convert_atoul(buf, &v)){
+            goto exit;
+        }
+        if(v < 0 || v > ADDR_MAX){
+            goto exit;
+        }
+        addr |= (v << shift);
+        if(idx == n) break;
+        shift -= BYTE_BITS;
+        s += idx+1;
+    }
+    err = 0;
+  exit:
+    addr = htonl(addr);
+    *address = (err ? 0 : addr);
+    return err;
+}
+
+#ifdef __KERNEL__
+/** Convert an address in network order to IPv4 dot notation.
+ * The return value is a static buffer which is overwritten on each call.
+ *
+ * @param inaddr address (in network order)
+ * @return address in dot notation
+ */
+char *inet_ntoa(struct in_addr inaddr){
+    static char address[16] = {};
+    uint32_t addr = ntohl(inaddr.s_addr);
+    snprintf(address, sizeof(address), "%d.%d.%d.%d",
+            (unsigned)((addr >> 24) & 0xff),
+            (unsigned)((addr >> 16) & 0xff),
+            (unsigned)((addr >>  8) & 0xff),
+            (unsigned)((addr      ) & 0xff));
+    return address;
+}
+
+
+/** Convert a string in IPv4 dot notation to an int in network order.
+ *
+ * @param address address in dot notation
+ * @param inp result of conversion (in network order)
+ * @return 0 on success, error code on error
+ */
+int inet_aton(const char *address, struct in_addr *inp){
+    int err = 0; 
+    unsigned long addr;
+    
+    err = get_inet_addr(address, &addr);
+    if(err) goto exit;
+    inp->s_addr = addr;
+  exit:
+    return err;
+}
+#endif
+
+/** Convert a hostname or IPv4 address string to an address in network order.
+ *
+ * @param name input hostname or address string
+ * @param address where to put the address
+ * @return 0 if address found OK, nonzero otherwise
+ */
+int get_host_address(const char *name, unsigned long *address){
+#ifdef __KERNEL__
+    return get_inet_addr(name, address);
+#else
+    struct hostent *host = gethostbyname(name);
+    if(!host){
+        return -EINVAL;
+    }
+    *address = ((struct in_addr *)(host->h_addr))->s_addr;
+    return 0;
+#endif
+}
+
+/** Convert a service name to a port (in network order).
+ *
+ * @param name service name
+ * @param port where to put the port
+ * @return 0 if service port found OK, negative otherwise
+ */
+int get_service_port(const char *name, unsigned long *port){
+#ifdef __KERNEL__
+    return -ENOSYS;
+#else
+    struct servent *service;
+    service = getservbyname(name, 0);
+    if(!service){
+        return -EINVAL;
+    }
+    *port = service->s_port;
+    return 0;
+#endif
+}
+
+/** Convert a port number (in network order) to a service name.
+ *
+ * @param port the port number
+ * @return service name if found OK, NULL otherwise
+ */
+char *get_port_service(unsigned long port){
+#ifdef __KERNEL__
+    return NULL;
+#else
+    struct servent *service = getservbyport(port, 0);
+    return (service ? service->s_name : NULL);
+#endif
+}
+
+/** Convert a decimal integer or service name to a port (in network order).
+ *
+ * @param s input to convert
+ * @param port where to put the port
+ * @return 0 if port found OK, -1 otherwise
+ */
+int convert_service_to_port(const char *s, unsigned long *port){
+    int err = 0;
+    unsigned long value;
+    if(convert_atoul(s, &value) == 0){
+        int ok = (0 <= value) && (value <= PORT_MAX);
+        if(ok){
+            value = htons((unsigned short)value);
+        } else {
+            err = -EINVAL;
+        }
+    } else {
+        err = get_service_port(s, &value);
+    }
+    *port = (err ? 0: value);
+    return err;
+}
+
+#define MAC_ELEMENT_N  6 // Number of elements in a MAC address.
+#define MAC_DIGIT_N    2 // Number of digits in an element in a MAC address.
+#define MAC_LENGTH    17 //((MAC_ELEMENT_N * MAC_DIGIT_N) + MAC_ELEMENT_N - 1)
+
+/** Convert a mac address from a string of the form
+ * XX:XX:XX:XX:XX:XX to numerical form (an array of 6 unsigned chars).
+ * Each X denotes a hex digit: 0..9, a..f, A..F.
+ * Also supports using '-' as the separator instead of ':'.
+ *
+ * @param mac_in string to convert
+ * @param mac destination for the value
+ * @return 0 on success, -1 on error
+ */
+int mac_aton(const char *mac_in, unsigned char *mac){
+    int err = 0;
+    int i, j;
+    const char *p;
+    char sep = 0;
+    unsigned char d;
+    if(!mac_in || strlen(mac_in) != MAC_LENGTH){
+        err = -1;
+        goto exit;
+    }
+    for(i = 0, p = mac_in; i < MAC_ELEMENT_N; i++){
+        d = 0;
+        if(i){
+            if(!sep){
+                if(*p == ':' || *p == '-') sep = *p;
+            }
+            if(sep && *p == sep){
+                p++;
+            } else {
+                err = -1;
+                goto exit;
+            }
+        }
+        for(j = 0; j < MAC_DIGIT_N; j++, p++){
+            if(j) d <<= 4;
+            if(*p >= '0' && *p <= '9'){
+                d += (*p - '0');
+            } else if(*p >= 'A' && *p <= 'F'){
+                d += (*p - 'A') + 10;
+            } else if(*p >= 'a' && *p <= 'f'){
+                d += (*p - 'a') + 10;
+            } else {
+                err = -1;
+                goto exit;
+            }
+        }
+        mac[i] = d;
+    }
+  exit:
+    return err;
+}
+
+/** Convert a MAC address from numerical form to a string.
+ *
+ * @param mac address to convert
+ * @return static string value
+ */
+char *mac_ntoa(const unsigned char *mac){
+    static char buf[MAC_LENGTH + 1];
+    int buf_n = sizeof(buf);
+
+    memset(buf, 0, buf_n);
+    snprintf(buf, buf_n, "%02x:%02x:%02x:%02x:%02x:%02x",
+             mac[0], mac[1], mac[2],
+             mac[3], mac[4], mac[5]);
+    buf[buf_n - 1] = '\0';
+    return buf;
+}
diff --git a/tools/vnet/libxutil/sys_net.h b/tools/vnet/libxutil/sys_net.h
new file mode 100644 (file)
index 0000000..6175494
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _XUTIL_SYS_NET_H_
+#define _XUTIL_SYS_NET_H_
+/** @file
+ *
+ * Replacement for standard network includes.
+ * Works in user or kernel code.
+ */
+
+extern int get_inet_addr(const char *s, unsigned long *address);
+extern unsigned long bits_to_mask(int n);
+extern int mask_to_bits(unsigned long mask);
+extern int get_host_address(const char *name, unsigned long *address);
+extern int get_service_port(const char *name, unsigned long *port);
+extern char *get_port_service(unsigned long port);
+extern int convert_service_to_port(const char *s, unsigned long *port);
+
+#ifdef __KERNEL__
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <asm/byteorder.h> 
+
+#ifndef htonl
+#define htonl(x) __constant_htonl(x)
+#endif
+
+#ifndef ntohl
+#define ntohl(x) __constant_ntohl(x)
+#endif
+
+#ifndef htons
+#define htons(x) __constant_htons(x)
+#endif
+
+#ifndef ntohs
+#define ntohs(x) __constant_ntohs(x)
+#endif
+
+#include <linux/in.h>
+extern char *inet_ntoa(struct in_addr inaddr);
+extern int inet_aton(const char *address, struct in_addr *inp);
+
+#else
+
+#include <limits.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+#endif
+
+extern char *mac_ntoa(const unsigned char *macaddr);
+extern int mac_aton(const char *addr, unsigned char *macaddr);
+
+#endif /* !_XUTIL_SYS_NET_H_ */
+
+
+
diff --git a/tools/vnet/libxutil/sys_string.c b/tools/vnet/libxutil/sys_string.c
new file mode 100644 (file)
index 0000000..22a8ae3
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef __KERNEL__
+#  include <linux/config.h>
+#  include <linux/module.h>
+#  include <linux/kernel.h>
+#  include <linux/errno.h>
+#else
+#  include <errno.h>
+#endif
+
+#include "allocate.h"
+#include "sys_string.h"
+
+/** Set the base to use for converting a string to a number.  Base is
+ * hex if starts with 0x, otherwise decimal.
+ *
+ * @param s input string
+ * @param base where to put the base
+ * @return rest of s to parse as a number
+ */
+inline static const char * convert_set_base(const char *s, int *base){
+    *base = 10;
+    if(s){
+        if(*s=='0'){
+            s++;
+            if(*s=='x' || *s=='X'){
+                *base = 16;
+                s++;
+            }
+        }
+    }
+    return s;
+}
+
+/** Set the sign to use for converting a string to a number.
+ * Value is 1 for positive, -1 for negative.
+ *
+ * @param s input string
+ * @param sign where to put the sign
+ * @return rest of s to parse as a number
+ */
+inline static const char * convert_set_sign(const char *s, int *sign){
+    *sign = 1;
+    if(s){
+        if(*s == '+'){
+            *sign = 1;
+            s++;
+        } else if (*s == '-'){
+            *sign = -1;
+            s++;
+        }
+    }
+    return s;
+}
+
+/** Get the numerical value of a digit in the given base.
+ *
+ * @param c digit character
+ * @param base to use
+ * @return numerical value of digit in range 0..base-1 or
+ * -1 if not in range for the base
+ */
+inline static int convert_get_digit(char c, int base){
+    int d;
+
+    if('0'<=c  && c<='9'){
+        d = c - '0';
+    } else if('a'<=c && c<='f'){
+        d = c - 'a' + 10;
+    } else if('A'<=c && c<='F'){
+        d = c - 'A' + 10;
+    } else {
+        d = -1;
+    }
+    return (d < base ? d : -1);
+}
+
+/** Convert a string to an unsigned long by parsing it as a number.
+ * Will accept hex or decimal in usual C syntax.
+ *
+ * @param str input string
+ * @param val where to put the result
+ * @return 0 if converted OK, negative otherwise
+ */
+int convert_atoul(const char *str, unsigned long *val){
+    int err = 0;
+    unsigned long v = 0;
+    int base;
+    const char *s = str;
+
+    if(!s) {
+        err = -EINVAL;
+        goto exit;
+    }
+    s = convert_set_base(s, &base);
+    for( ; !err && *s; s++){
+        int digit = convert_get_digit(*s, base);
+        if(digit<0){
+            err = -EINVAL;
+            goto exit;
+        }
+        v *= base;
+        v += digit;
+    } 
+  exit:
+    *val = (err ? 0 : v);
+    return err;
+}
+
+/** Convert a string to a long by parsing it as a number.
+ * Will accept hex or decimal in usual C syntax.
+ *
+ * @param str input string
+ * @param val where to put the result
+ * @return 0 if converted OK, negative otherwise
+ */
+int convert_atol(const char *str, long *val){
+    int err = 0;
+    unsigned long v = 0;
+    int base, sign = 1;
+    const char *s = str;
+
+    if(!s) {
+        err = -EINVAL;
+        goto exit;
+    }
+    s = convert_set_sign(s, &sign);
+    s = convert_set_base(s, &base);
+    for( ; !err && *s; s++){
+        int digit = convert_get_digit(*s, base);
+        if(digit<0){
+            err = -EINVAL;
+            goto exit;
+        }
+        v *= base;
+        v += digit;
+    } 
+    if(sign < 0) v = -v;
+  exit:
+    *val = (err ? 0 : v);
+    return err;
+}
+
+/** Combine a directory path with a relative path to produce
+ * a new path.
+ *
+ * @param s directory path
+ * @param t relative path
+ * @return new combined path s/t
+ */
+int path_concat(char *s, char *t, char **val){
+    int err = 0;
+    int sn, tn, vn;
+    char *v;
+    sn = strlen(s);
+    if(sn > 0 && s[sn-1] == '/'){
+        sn--;
+    }
+    tn = strlen(t);
+    if(tn > 0 && t[0] == '/'){
+        tn--;
+    }
+    vn = sn+tn+1;
+    v = (char*)allocate(vn+1);
+    if(!v){
+        err = -ENOMEM;
+        goto exit;
+    }
+    strncpy(v, s, sn);
+    v[sn] = '/';
+    strncpy(v+sn+1, t, tn);
+    v[vn] = '\0';
+  exit:
+    *val = (err ? NULL : v);
+    return err;    
+}
diff --git a/tools/vnet/libxutil/sys_string.h b/tools/vnet/libxutil/sys_string.h
new file mode 100644 (file)
index 0000000..88d9d8d
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _XUTIL_SYS_STRING_H_
+#define _XUTIL_SYS_STRING_H_
+/** @file
+ * Replacement for standard string includes.
+ * Works in user or kernel code.
+ */
+/*============================================================================*/
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <stdarg.h>
+#include "allocate.h"
+
+#if 0
+static inline int tolower(int c){
+    return (c>='A' && c<='Z' ? (c-'A')+'a' : c);
+}
+#endif
+
+static inline int isalpha(int c){
+    return (c>='A' && c<='Z') || (c>='a' && c<='z');
+}
+
+static inline int isdigit(int c){
+   return (c>='0' && c<='9');
+}
+
+#if 0
+static inline int strcasecmp(const char *s1, const char *s2){
+       int c1, c2;
+
+       do {
+               c1 = tolower(*s1++);
+               c2 = tolower(*s2++);
+       } while (c1 && c1 == c2);
+       return c1 - c2;
+}
+#endif
+
+static inline char * strdup(const char *s){
+    int n = (s ? 1+strlen(s) : 0);
+    char *copy = (n ? allocate(n) : NULL);
+    if(copy){
+        strcpy(copy, s);
+    }
+    return copy;
+}
+
+/*============================================================================*/
+#else
+#include <string.h>
+#include <stdio.h>
+
+#ifndef _GNU_SOURCE
+static inline size_t strnlen(const char *s, size_t n){
+    int k = 0;
+    if(s){
+       for(k=0; *s && k<n; s++, k++){}
+    }
+    return k;
+}
+#endif
+
+#endif
+/*============================================================================*/
+
+extern int convert_atoul(const char *s, unsigned long *v);
+extern int convert_atol(const char *s, long *v);
+extern int path_concat(char *s, char *t, char **val);
+
+#endif /* !_XUTIL_SYS_STRING_H_ */
diff --git a/tools/vnet/libxutil/util.c b/tools/vnet/libxutil/util.c
new file mode 100644 (file)
index 0000000..0ac388b
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2002 - 2004 Mike Wray <mike.wray@hp.com>.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or  (at your option) any later version. This library is 
+ * distributed in the  hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include "sys_net.h"
+#include "sys_string.h"
+
+#ifndef __KERNEL__
+#  include <grp.h>   
+#  include <pwd.h>  
+#endif
+
+#include "util.h"
+
+
+/** @file Various utility functions.
+ */
+
+/** Print an address (in network order) as an IPv4 address string
+ * in dot notation.
+ *
+ * @param io where to print address
+ * @param address to print (in network order)
+ * @return bytes printed
+ */
+int print_address(IOStream *io, unsigned long address){
+#ifdef __KERNEL__
+    address = ntohl(address);
+    return IOStream_print(io, "%u.%u.%u.%u", 
+                          (unsigned)((address >> 24) & 0xff),
+                          (unsigned)((address >> 16) & 0xff),
+                          (unsigned)((address >>  8) & 0xff),
+                          (unsigned)((address      ) & 0xff));
+#else
+    struct in_addr inaddr = { s_addr: address };
+    return IOStream_print(io, inet_ntoa(inaddr));
+#endif
+}
+
+/** Get the protocol number for a protocol.
+ *
+ * @param name protocol name
+ * @param protocol where to put the protocol number
+ * @return 0 if OK, error otherwise
+ */  
+int get_protocol_number(char *name, unsigned long *protocol){
+#ifdef __KERNEL__
+    return -1;
+#else
+    struct protoent *proto = getprotobyname(name);
+    if(!proto){
+       return -1;
+    }
+    *protocol = proto->p_proto;
+    return 0;
+#endif
+}
+
+/** Get the protocol name for a protocol number.
+ *
+ * @param protocol number
+ * @return name or null
+ */
+char *get_protocol_name(unsigned long protocol){
+#ifdef __KERNEL__
+    return 0;
+#else
+    struct protoent *proto = getprotobynumber(protocol);
+    if(!proto){
+       return 0;
+    }
+    return proto->p_name;
+#endif
+}
+
+/** Get the host name for an address.
+ *
+ * @param addr address
+ * @return host name or null
+ */
+char *get_host_name(unsigned long addr){
+#ifdef __KERNEL__
+    return 0;
+#else
+    struct in_addr inaddr;
+    struct hostent *host = 0;
+
+    inaddr.s_addr = addr;
+    host = gethostbyaddr((char*)&inaddr, sizeof(inaddr), AF_INET);
+    if(!host) return NULL;
+    return host->h_name;
+#endif
+}
diff --git a/tools/vnet/libxutil/util.h b/tools/vnet/libxutil/util.h
new file mode 100644 (file)
index 0000000..b4a1705
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2002 - 2004 Mike Wray <mike.wray@hp.com>.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or  (at your option) any later version. This library is 
+ * distributed in the  hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#ifndef _XEN_LIB_UTIL_H_
+#define _XEN_LIB_UTIL_H_
+
+#include "iostream.h"
+
+extern int print_address(IOStream *io, unsigned long address);
+extern int get_protocol_number(char *name, unsigned long *protocol);
+extern char *get_protocol_name(unsigned long protocol);
+extern char *get_host_name(unsigned long addr);
+
+#endif /* ! _XEN_LIB_UTIL_H_ */
index 366c2fc9b94f0766ce4eeebd7b48537919f8b2ef..2bc07b8f9201a7b1c7f3273cca983d12a03ee853 100644 (file)
@@ -24,7 +24,7 @@ else
 SRC_DIR=$(src)/
 endif
 
-LIB_DIR := $(SRC_DIR)../../libxutil
+LIB_DIR := $(SRC_DIR)../libxutil
 
 VNET_SRC :=
 VNET_SRC += esp.c
index 3783fa38336cc07396a960c135bf281ae3859293..a7afa94384e0c69f8a0246e56c52aa76152b0e2c 100644 (file)
@@ -25,7 +25,7 @@ include $(XEN_ROOT)/tools/Rules.mk
 
 VNETD_INSTALL_DIR = /usr/sbin
 
-LIB_DIR = $(XEN_LIBXUTIL)
+LIB_DIR = ../libxutil
 VNET_DIR = ../vnet-module
 
 INCLUDES += -I$(LIB_DIR)
index e3b4380411dfb1ef569008f3e241807c4e94b3ad..c3c4bdfa82acdec0c59f471a255090d3e7cfc400 100644 (file)
@@ -15,7 +15,6 @@ CFLAGS   = -Wall -Werror -g3 -D _XOPEN_SOURCE=600
 
 CFLAGS  += -I $(XEN_XC)
 CFLAGS  += -I $(XEN_LIBXC)
-CFLAGS  += -I $(XEN_LIBXUTIL)
 
 SRCS    :=
 SRCS    += ctrl_interface.c
@@ -34,11 +33,11 @@ clean:
        $(RM) *.a *.so *.o *.rpm $(BIN) xcsdump
 
 xcsdump: xcsdump.c dump.c
-       $(CC) $(CFLAGS) -o xcsdump xcsdump.c -L$(XEN_LIBXC) -L$(XEN_LIBXUTIL) \
-              ctrl_interface.c evtchn.c dump.c -lxc -lxutil
+       $(CC) $(CFLAGS) -o xcsdump xcsdump.c -L$(XEN_LIBXC) \
+              ctrl_interface.c evtchn.c dump.c -lxc
 
 $(BIN): $(OBJS)
-       $(CC) $(CFLAGS) $^ -o $@ -L$(XEN_LIBXC) -L$(XEN_LIBXUTIL) -lxc -lxutil 
+       $(CC) $(CFLAGS) $^ -o $@ -L$(XEN_LIBXC) -lxc 
 
 $(OBJS): $(HDRS)
 
index 1175ff57139ed58dd4b2b910d18ae1d80f12a4cf..d4e0ebad0fae4153dd872b177a2eb172d5e74b00 100644 (file)
@@ -30,7 +30,7 @@ PROG_DEP = .*.d
 
 PROGRAMS               = xc_restore xc_save
 
-LDLIBS                 = -L$(XEN_LIBXC) -lxc -L$(XEN_LIBXUTIL) -lxutil
+LDLIBS                 = -L$(XEN_LIBXC) -lxc
 
 .PHONY: all
 all: build
index faa0a46bf8734ff41717e7d12776b8aca245e4f2..329d71c3eed3e3325af6b59073a77ff339151700 100644 (file)
@@ -10,7 +10,6 @@ CFLAGS  += -Wall -Werror -O3
 
 CFLAGS  += -I $(XEN_XC)
 CFLAGS  += -I $(XEN_LIBXC)
-CFLAGS  += -I $(XEN_LIBXUTIL)
 
 HDRS     = $(wildcard *.h)
 OBJS     = $(patsubst %.c,%.o,$(wildcard *.c))
@@ -37,4 +36,4 @@ clean:
        $(RM) *.a *.so *.o *.rpm $(BIN)
 
 %: %.c $(HDRS) Makefile
-       $(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -L$(XEN_LIBXUTIL) -lxc -lxutil
+       $(CC) $(CFLAGS) -o $@ $< -L$(XEN_LIBXC) -lxc